Migrating from state-aware orchestration to dbt State Preview
dbt State improves upon state-aware orchestration in a few key ways:
- Works everywhere — dbt State works with dbt Core, Fusion, and dbt platform, as well as external orchestrators, across both development and deployment environments.
- Smarter data freshness tracking — dbt State tracks data freshness across the DAG and automatically propagates it through models materialized as views. Unlike state-aware orchestration's
build_afterconfig which compares against the model's last successful execution, dbt State'slag_tolerancecompares against the freshness of the underlying data. - Advanced change detection — dbt State can detect and ignore file modifications that don't change actual transformation logic, such as adding a comment or cleaning up whitespace.
If you were using state-aware orchestration prior to June 1, 2026, you can continue using it. Your dbt State trial will be extended until the billing period begins on September 1, 2026. If your trial wasn't extended, contact your account team. For details on billing after the trial ends, refer to dbt State usage and pricing.
While dbt State is in preview, there is no required migration timeline — dbt Labs will communicate a timeline when dbt State reaches general availability.
Migrating your configuration
Much of dbt State's configuration will feel familiar if you've used state-aware orchestration, but there is one significant difference: the build_after configs have moved out of the freshness block and into a new state block.
To migrate to dbt State, move your configs from freshness.build_after to the new state block. Refer to the following table for the full mapping.
| Loading table... |
In the dbt Fusion engine, dbt State will automatically fall back to your existing build_after configs if lag_tolerance and require_fresh_data_from are not set. This means you can enable dbt State without updating your project configs first.
Examples
You can set these configs at the project level in dbt_project.yml or at the model level in a .yml file.
Project-level:
Before (state-aware orchestration)
models:
+freshness:
build_after:
count: 1
period: day
updates_on: any
After (dbt State)
models:
+state:
lag_tolerance: 1d
require_fresh_data_from: any
Model-level:
Before (state-aware orchestration)
models:
- name: my_model
config:
freshness:
build_after:
count: 1
period: day
updates_on: any
After (dbt State)
models:
- name: my_model
config:
state:
lag_tolerance: 1d
require_fresh_data_from: any
Testing the migration
You can run both configs side by side while validating. State-aware orchestration reads freshness.build_after and dbt State reads the state block, so they won't interfere with each other. Once you're confident everything looks right, remove the build_after configs.
models:
+freshness:
build_after: # state-aware orchestration (remove once migrated)
count: 1
period: day
updates_on: any
+state: # dbt State
lag_tolerance: 1d
require_fresh_data_from: any
Known differences from state-aware orchestration
State-aware orchestration and dbt State differ in a few ways:
-
More models rebuilding than expected: If you notice more rebuilds after you migrate, the most common causes are:
- Views with
select *: dbt State can't determine which columnsselect *resolves to without querying the upstream schema, so it always rebuilds these views rather than risk reusing a stale result. - Non-determinism in Jinja-templated SQL: Macros like
dbt_utils.get_relations_by_patternwithdbt_utils.union_relationscan return relations in a different order on each run, which produces different compiled SQL. dbt State detects a new hash and rebuilds the model. If that model has downstream dependencies, those models rebuild, too.
Refer to Why is my model being rebuilt instead of reused? for details on each cause and how to diagnose them.
- Views with
-
build_aftervslag_tolerance: Both configs reduce how often a model runs when upstream data is frequently fresh, but they work differently:freshness.build_after(for example,{count: 4, period: hour}) skips the model unless the configured interval has elapsed and upstream sources have new data since the last run. A SQL change alone does not trigger a rebuild; both conditions must be met.state.lag_tolerance(for example,4h) skips the model unless upstream data is newer than the model's last run by at least the configured interval. Unlikebuild_after, a detected SQL change triggers a rebuild.
-
Efficient Testing not yet available: State-aware orchestration offers Efficient Testing (private beta); dbt State doesn't support it yet.
Related docs
Was this page helpful?
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.