Every hour, on a schedule, your dbt job rebuilds every model in your project. The staging models run because they always run. The intermediate joins run because they always run. The mart that powers the executive dashboard runs because, well, it always runs — even when not a single row in any upstream table changed since the last execution.
This is the pattern most teams have lived with for years. It is simple, predictable, and expensive. And as of September 16, 2026 — announced at dbt Summit in Las Vegas — there is a better way.
dbt State went generally available this week. It checks your warehouse metadata and compares model SQL fingerprints to your previous run’s manifest, then decides for each model: BUILD it (logic or data changed), CLONE it (data is fresh enough to reuse), or SKIP it (nothing changed, mark success instantly). The result, in production at companies like RxBenefits and Virgin Media O2, is a 25–59% cut in warehouse compute and significantly faster job run times — without changing a single line of your transformation SQL.

TL;DR
- dbt State evaluates each model on every run and assigns one of four actions: REBUILD (logic or upstream changed), CLONE (use last result — data fresh enough), or SKIP (nothing changed). The decision logic runs before any warehouse query fires.
- It works with dbt v1.7 through v2, across Snowflake, BigQuery, Databricks, and Redshift. You don’t need dbt v2 to start — but v2’s Rust engine makes the evaluation dramatically faster on large projects.
lag_toleranceis the key new model-level config: it declares how stale a model is allowed to be before it must be rebuilt. A mart that’s fine with 24h-old data can run on a once-daily schedule automatically, while afct_orderswith a 5-minute tolerance gets rebuilt the moment upstream data changes.- dbt State is a paid add-on to the dbt platform (dbt Cloud). It is not available as a standalone open-source feature in dbt-oss. The
--deferandstate:modifiedselector in dbt Core remain free and open-source, but they require you to manage the state artifact yourself and don’t include the warehouse metadata check. - The MCP Server integration announced at dbt Summit 2026 means AI agents querying your dbt project’s lineage can now see freshness status per model — which makes
lag_tolerancea governance contract, not just a cost lever.
How dbt State Evaluates Every Model
The evaluation logic runs before any warehouse query fires. dbt State pulls two things: the current manifest (your project’s compiled SQL and config fingerprints) and warehouse metadata for each model’s underlying table. It compares both against the previous run’s state artifact. The result is a per-model action, decided before the job touches compute.

📷 three checks, four outcomes — all evaluated before a single warehouse query fires
The CLONE action is the one most teams don’t expect. When upstream data hasn’t changed and the model is outside its lag_tolerance window (meaning it’s already stale but not yet due for a rebuild), dbt State clones the last successful result — copying the table metadata rather than re-executing the SQL. The downstream model sees a fresh table reference, the scheduler marks the task successful, and no compute was consumed. This is what accounts for the bulk of the cost savings in the production numbers above.
What Actually Changes Per Run

📷 only the models whose sql or upstream data changed get rebuilt — the rest are skipped or cloned without touching compute
The example above shows a realistic scenario: one staging model changed (an engineer added a new column), which cascades to the intermediate model that joins it, which cascades to the mart. Three models rebuild. Five skip. If those five models typically consume 62% of your job’s warehouse credit spend, that’s 62% saved on that run — every run where this pattern holds.
The cascade detection is automatic. dbt State uses your DAG’s lineage to trace which downstream models depend on a changed model, and flags those for rebuild too. You don’t configure cascades manually. The same lineage your DAG tracks for documentation is what dbt State uses to propagate change detection.
Setting Up dbt State
Configuration is two steps: enable the feature in your job settings and add lag_tolerance to the models that should define their own freshness contract.
Enable dbt State on a job
# In dbt Cloud: Job Settings → Advanced → Enable dbt State
# Or via the dbt platform UI under the job's configuration panel
# For local / self-hosted runs with dbt v1.7+:
# Set the state artifact path — dbt State compares against this
dbt run --state path/to/previous/run/artifacts --defer
dbt State (GA, paid) vs –defer (free, open-source): the --defer flag and state:modified selector have existed in dbt Core since v1.1 and are fully open-source under Apache 2.0. They require you to store and pass the state artifact manually and don’t include warehouse metadata checks. dbt State (the GA product) automates the artifact lifecycle, adds the warehouse metadata evaluation step, and includes the CLONE action. If you’re on dbt Core and not on the dbt platform, --defer is still a meaningful free starting point.
Add lag_tolerance to your models
lag_tolerance is a model-level config that tells dbt State how stale this model’s data is allowed to be. It’s declared in your model’s YAML config and becomes part of the compiled manifest.
# models/marts/fct_orders.yml
models:
- name: fct_orders
description: "Order-level fact table, refreshed near-real-time."
config:
lag_tolerance: "5 minutes" # rebuild if upstream data is > 5min old
- name: dim_products
description: "Product dimension, refreshes once daily."
config:
lag_tolerance: "24 hours" # skip up to 24h before forcing rebuild
- name: dim_customers
description: "Customer dimension — changes are rare, 6h tolerance fine."
config:
lag_tolerance: "6 hours"
Once lag_tolerance is set, dbt State uses it to decide the SKIP vs CLONE vs REBUILD outcome for that model on every run. A model with no lag_tolerance set defaults to always rebuilding if upstream data changed — the safe, conservative behaviour.

📷 lag_tolerance moves freshness logic from the scheduler into the model — the right place for it to live
The before/after here is architectural, not just cosmetic. When freshness is a scheduler setting, it’s invisible to anyone reading your model code — and it’s invisible to AI agents querying your project’s lineage through the dbt MCP Server. When it’s lag_tolerance in the model YAML, it’s part of the model’s contract: auditable, version-controlled, and queryable by anything that reads your dbt manifest.
The Four Actions: BUILD, CLONE, SKIP, DEFER
| Action | When it fires | Warehouse compute? | Result |
|---|---|---|---|
| BUILD | SQL or config changed, OR upstream data refreshed and model is past lag_tolerance | Yes — full model run | New table written |
| CLONE | Upstream data refreshed but model is within lag_tolerance | No — metadata copy only | Last result reused via zero-copy clone |
| SKIP | Nothing changed — SQL, config, and upstream data all identical to last run | No | Task marked success, no compute touched |
| DEFER | Model not in scope for this run (e.g. CI run scoped to modified models only) | No — references upstream environment | Uses production artifact, not dev rebuild |
DEFER is worth calling out separately because it predates dbt State and is often confused with it. DEFER is the --defer flag used in CI: when running a slim CI job scoped to state:modified+, models outside the scope defer to the production environment rather than rebuilding from scratch. dbt State’s BUILD/CLONE/SKIP logic sits on top of DEFER — they solve different problems and work together.
dbt State and AI Agents
One of the less-discussed implications of dbt State is what it means for agentic workflows. If you’re running LLM-driven pipelines in Airflow that trigger dbt jobs, or using the dbt MCP Server to let AI agents query your project — lag_tolerance becomes a governance guardrail, not just a cost setting.
Before dbt State, an AI agent with access to trigger a dbt run could rebuild your entire DAG on every invocation. That’s expensive and often unnecessary. With lag_tolerance set per model, dbt State enforces the freshness contract regardless of what triggered the run — a human, a scheduler, or an agent. The agent cannot force a rebuild of dim_products that’s only 2 hours old when the model declares a 24-hour tolerance. The infrastructure enforces it.
This also matters for the dbt MCP Server announced GA at dbt Summit 2026: agents querying your dbt project’s lineage and metrics can now see lag_tolerance as part of model metadata, letting them make informed decisions about whether a model’s data is fresh enough for a given question without triggering an unnecessary rebuild.
The Gotchas
dbt State (the GA product) is a paid dbt platform feature — not open-source.The confusion comes from dbt Core’s long-standing --defer and state:modified selectors, which are free and Apache 2.0. dbt State (GA) is a separate product that automates state artifact management, adds warehouse metadata evaluation, and includes CLONE. It requires a dbt Cloud account. If you’re self-hosting dbt Core, you can get partial coverage with --defer and a CI artifact pipeline, but the warehouse metadata check and automatic CLONE action are not available without the platform.
lag_tolerance with no upstream change monitoring is half the feature.lag_tolerance tells dbt State how stale a model is allowed to be. But dbt State also needs to know when upstream data actually changed — which it determines from warehouse metadata. On Snowflake and BigQuery this works out of the box. On Redshift and Databricks, table-level metadata freshness signals vary by storage format and configuration. Test the upstream detection on your specific adapter before assuming it works correctly.
The state artifact must match the target environment.dbt State compares your current run against a previous run’s artifact. If you run dev builds against a dev schema and then compare against a production artifact, the comparison may see false-positive changes (different schemas, different table names). Always compare like-for-like: production artifacts against production runs, dev artifacts against dev runs. The dbt platform manages this automatically; on self-hosted setups this is your responsibility.
Models with Python logic can’t be CLONED on all adapters.Python models in dbt (dbt-py) use a different execution path than SQL models. On Snowflake, Python model results can be cloned. On BigQuery and Databricks, Python model CLONE support is adapter-dependent and may fall back to SKIP or BUILD depending on your version. Check the dbt State setup docs for your adapter’s current support matrix before setting lag_tolerance on Python models.
Incremental models interact with dbt State differently than table models.For an incremental model, dbt State still evaluates whether SQL or config changed. But if the model is configured as incremental and upstream data refreshed, dbt State rebuilds using the incremental strategy — it does not CLONE the last full result. This is correct behaviour, but it means incremental models with frequent upstream updates may not see the same CLONE savings as table models. If you’ve been working through the antipatterns we covered in our incremental model guide, dbt State respects all those strategies exactly as configured.
The One Principle
“Put freshness in the model, not the scheduler. lag_tolerance is a contract — version-controlled, auditable, and enforceable by infrastructure, not by whoever remembers to update the cron.”
FAQ
What is dbt State and when did it go GA?
dbt State is a dbt platform feature that evaluates each model on every run and assigns an action — BUILD, CLONE, or SKIP — based on whether the model’s SQL changed, whether upstream data refreshed, and whether the model is within its declared lag_tolerance freshness window. It went generally available on September 16, 2026, announced at dbt Summit in Las Vegas. It runs on dbt v1.7 through v2, across Snowflake, BigQuery, Databricks, and Redshift.
Is dbt State free or a paid feature?
dbt State (the GA product with automatic warehouse metadata evaluation and CLONE) is a paid add-on to the dbt platform (dbt Cloud). The related open-source features — the –defer flag and state:modified selectors — remain free and Apache 2.0 licensed in dbt Core. They require manual state artifact management and don’t include the warehouse metadata check or automatic CLONE action.
What does lag_tolerance do in dbt?
lag_tolerance is a model-level config that declares how stale a model’s data is allowed to be before it must be rebuilt. Set it in your model’s YAML config — for example, “24 hours” for a slowly-changing dimension or “5 minutes” for a near-real-time fact table. dbt State reads this at runtime and uses it to decide whether to CLONE (reuse last result — data is fresh enough) or SKIP (nothing changed at all) rather than running a full rebuild.
What’s the difference between CLONE and SKIP in dbt State?
SKIP fires when nothing changed at all — SQL, config, and upstream data are all identical to the last run. CLONE fires when upstream data refreshed but the model is still within its lag_tolerance window, meaning it doesn’t need to rebuild yet. CLONE copies the table metadata (a zero-copy operation on Snowflake) so downstream models see a valid reference without any compute. Both actions consume no warehouse compute; CLONE is the one that handles partial staleness gracefully.
Do I need dbt v2 to use dbt State?
No. dbt State works with dbt v1.7 through v2. You don’t need to migrate to v2 to start saving on compute. That said, dbt v2’s Rust-based engine evaluates the state logic significantly faster on large projects — so teams with hundreds of models will see evaluation-time improvements by upgrading, on top of the compute savings from State itself.
How does dbt State interact with incremental models?
For incremental models, dbt State still evaluates SQL and config changes. If the model needs to run, it uses your configured incremental strategy (merge, insert-overwrite, etc.) as normal. Incremental models do not get CLONE — if upstream data refreshed, dbt State rebuilds them incrementally rather than reusing the last result. Models configured as table or view materializations benefit most from CLONE.
Related reading: dbt data lineage and DAG guide · dbt incremental model antipatterns · Running LLM tasks in Airflow with common.ai · Using MCP Servers with Snowflake · Snowflake Cortex AI token monitoring · dbt State product page (official) · dbt State setup docs (official) · dbt Summit 2026 announcements (official)
