If a dbt project has slow models, where should an engineering team actually start? Not with the model that takes the longest to build. That is the intuitive place to look, and it is usually the wrong one.
dbt model optimization done well starts with the DAG, because the DAG tells you something query-level profiling cannot: how much of the pipeline is waiting on any single model to finish. A model that takes six minutes and has forty downstream dependents is a bigger problem than a model that takes twenty minutes and has none. This piece walks through the order that actually works, based on how dbt project complexity tends to accumulate in practice.
1. Start With the DAG, Not the Slowest Query
Every dbt project has a dependency graph, whether or not the team has ever looked at it as a whole. The DAG shows lineage: which models feed which other models, all the way from source tables to the marts consumed by BI tools. What it does not show, by default, is cost or runtime per node. Those live in separate run logs.
The first useful step in dbt model optimization is combining the two views: overlay run duration onto the DAG so you can see not just what depends on what, but which nodes sit on the longest or busiest paths through the graph.
2. Map Dependents, Not Just Dependencies
Most engineers reflexively check what a model depends on. Fewer check what depends on it, and that second number is what actually determines blast radius.
+-------------+
| stg_orders |
+------+------+
|
+---------------+---------------+
| | |
v v v
fct_revenue fct_shipping fct_returns
| |
v v
rpt_exec_dash rpt_returns_qa
In this shape, stg_orders is a small, fast-building staging model. It is also the single point every downstream fact and report depends on. If stg_orders runs slow, or runs unreliably, every model beneath it inherits that problem, regardless of how well fct_revenue or rpt_exec_dash are individually optimized. This is the pattern behind a rule worth keeping in mind:
The biggest performance problem in a mature dbt environment is rarely the slowest model. It is the model with the most downstream dependents that nobody has profiled recently.
3. Full Refresh vs. Incremental: A Decision, Not a Default
Incremental models exist so a run processes only new or changed rows instead of rebuilding a table from scratch. In practice, a lot of large models stay on full refresh well past the point where incremental logic would clearly be cheaper, and the reason is rarely technical necessity. It is usually that the team does not fully trust the incremental logic to handle late-arriving records, backfills, or schema drift correctly, so a full refresh feels like the safer default even though it costs far more compute on every run.
That is a legitimate engineering tradeoff, but it should be made deliberately, not inherited from whatever the model looked like when it was first written. A model is a strong incremental candidate when it has high volume, a reliable unique key, and data that only partially changes between runs. If those conditions hold and the model is still full-refreshed, that is worth treating as a backlog item, not a permanent state.
4. Materialization Strategy Matters More Than Query Syntax
Teams often reach for query-level tuning, rewriting joins, adjusting filters, before checking whether a model's materialization strategy fits its actual usage pattern. A model queried constantly by dashboards benefits from being a table, not a view, even at the cost of build time, because it shifts compute from every read to one write. A model rarely queried directly might be fine as a view or an ephemeral model, saving storage and build time it does not need.
This decision is often made once, early, and never revisited as usage patterns change. A model built as a view during development sometimes stays a view long after it becomes a heavily queried mart, quietly pushing compute cost onto every downstream query instead of consolidating it into a single scheduled build.
5. A Concrete Example
Consider a mid-size retailer's dbt project with roughly 300 models. The slowest single model in the daily run is a returns-reconciliation model that takes eighteen minutes. It has three downstream dependents. Meanwhile, a staging model for order events takes four minutes but sits upstream of sixty other models, including every revenue and inventory report the executive team looks at each morning.
Optimizing the eighteen-minute model saves eighteen minutes, once, in isolation. Optimizing the four-minute staging model, or converting it from a full refresh to incremental, shortens the critical path for sixty downstream builds and every analyst waiting on them. The DAG, not the run-duration leaderboard, is what makes that difference visible.
6. A Short Diagnostic Checklist
Before optimizing anything, it helps to answer four questions:
Which models have the highest number of downstream dependents, based on the actual DAG, not assumptions
Which of those high-dependent models are still on full refresh
Which models are materialized as views despite being queried directly and frequently
Which models have no clear owner or documented reason for existing
The first pass through this list usually surfaces two or three models responsible for a disproportionate share of total run time and cost. That is where dbt model optimization work should start.
7. Where Model-Level Optimization Hits Its Ceiling
Model-level fixes, materializations, incremental strategies, query rewrites, solve real problems, and they have a ceiling. Once a project has grown to the point where dependency mapping requires tooling rather than memory, where similar logic has plausibly been built in more than one place, and where nobody can confidently say which models are safe to retire, the constraint is no longer any individual model's SQL. It is the absence of an accurate, current picture of the project's dependency structure.
That gap is closer to a documentation and metadata problem than a performance-tuning problem, and it tends to need different tooling to close rather than another optimization pass. Teams working through this at scale sometimes reach for automated dependency and lineage mapping, an approach 3XDE's Metadata Intelligence accelerator applies across complex legacy and modern data estates, rather than trying to reconstruct the graph by hand.
8. When the Problem Is Bigger Than the Model
If your diagnostic checklist keeps surfacing the same answer, that a handful of undocumented, high-dependent models are driving most of the cost and nobody is confident touching them, that is a signal worth taking seriously. It usually means the project has outgrown model-by-model optimization as the right unit of work, and an actual architecture-level look at the estate is what comes next.
Key takeaway
Effective dbt model optimization starts with understanding the dependency graph, not just tuning the slowest query. When model-level fixes stop delivering meaningful gains, dependency and lineage analysis can reveal where the larger performance bottlenecks sit. 3XDE’s Metadata Intelligence helps teams map complex data environments and uncover these dependencies at scale.


Top comments (0)