Skip to main content
Private preview. Paradime State is in private preview. To get early access for your workspace, reach out to the Paradime team at support@paradime.io.
Paradime State makes dbt run, dbt build, and dbt snapshot state-aware. Before it builds anything, it compares each model, seed, snapshot, and test (each node) with its last successful build. If neither the node’s code nor its upstream data has changed, the node is skipped. Skipped nodes cost no warehouse compute, so a run that used to rebuild your whole project builds only what changed.
Paradime State runs on dbt™ 2.0-latest, and nothing in your project needs to change to start using it. To turn it on, see Turn on Paradime State.

How a run decides

Every state-aware dbt run, dbt build, or dbt snapshot goes through four steps:
  1. Compile. dbt™ compiles the project, so Paradime State has each node’s SQL and configuration. Data tests are compared by their definition instead, so they aren’t compiled in this step. If the project fails to compile, the command runs as plain dbt™.
  2. Check the warehouse. In the background, Paradime State reads when each table the run depends on last changed, from warehouse metadata or from a source’s loaded_at_field.
  3. Decide. Each node is compared with its last successful build and gets one of three outcomes: skip, clone, or build.
  4. Build and record. Only the nodes that need it are built. Paradime State records the new baseline and prints a summary at the end of the run.

Skip, clone, or build

A node’s logic is its compiled SQL, compared in a normalized form so that whitespace and formatting don’t count, together with its materialization and the configurations that change what gets built. For a data test, the logic is its definition: the generic test and its arguments (or a singular test’s SQL), the column and the models or sources it tests, and the macros it calls. See What counts as a change. When a node builds or is cloned, every node downstream of it builds too, in the same run. On Snowflake, BigQuery, Databricks, and Redshift, while clones are allowed, a downstream node whose identical logic is already built in another schema waits until its upstream has built and is then decided again, so it can be cloned instead of rebuilt. The summary lists these nodes under rejudged.

What always builds

Some nodes can’t be judged safely, so Paradime State builds them on every run:
  • Incremental models, Python models, and models with a custom materialization.
  • Models that select * directly from a ref() or source(). Their SQL doesn’t change when the upstream gains a column, so Paradime State can’t tell whether the result would differ. A select * from a CTE is fine.
Views work differently. A view holds no data, so it’s reused whenever its SQL is unchanged, even after new data arrives upstream. The tables that read from the view rebuild when the data behind it changes. Only tables are cloned. In development, incremental models and snapshots can instead be copied from production before they build, with pre_clone.

Tests, seeds, and snapshots in dbt build

  • Data tests skip when the test and the data it tests are unchanged, and their previous result is replayed. A replayed failure still fails the run.
  • A model whose test failed is rebuilt on the next run, so the test runs again.
  • Seeds skip when the CSV file and its load settings are unchanged.
  • Snapshots skip when their SQL, configuration, and upstream data are unchanged, in dbt build and in dbt snapshot. Any new upstream data runs them, whatever their lag_tolerance.
  • A snapshot that reads a model the same build rebuilds runs in one pass with the models, so it runs after that model and captures its new data, as in plain dbt™.
  • --resource-type and --exclude-resource-type limit which resource types dbt build processes, as in plain dbt™.

Where it runs

Only dbt run, dbt build, and dbt snapshot are state-aware. Every other command, including dbt seed and dbt test on their own, runs exactly as it would without Paradime State.
Selectors that compare against a previous run’s manifest, such as state:modified+, don’t work while Paradime State is on. Keep Paradime State off for schedules that use them, typically Turbo CI and continuous deployment. See Schedules that select with state: methods.

Supported warehouses

On any other warehouse, runs build as plain dbt™. On every warehouse, declare a loaded_at_field on sources whose table metadata doesn’t change when data lands, such as views and external tables.

If the state service is unavailable

Runs don’t fail because Paradime State is unavailable. If it can’t reach its service, the rest of the run builds normally, and a paradime-state: notice in the log says why. The next run uses Paradime State again.

If the project fails to compile

If a node in the run’s selection fails to compile, Paradime State can’t judge the run, so it stands aside and runs your command as plain dbt™. dbt™ then fails that node, skips the nodes that depend on it, and builds the rest. A paradime-state: notice says the compile failed, and the summary says that Paradime State stood aside and why. Runs use Paradime State again once the project compiles.

Coming from dbt™ State

Paradime State reads the same state configurations as dbt™ State (lag_tolerance, require_fresh_data_from, pre_clone, and evaluate_volatile_sql), so a project already configured for dbt™ State carries over. Two differences:
  • Set compare_unrendered_code under meta, not state. See compare_unrendered_code.
  • The older freshness.build_after settings from dbt™ state-aware orchestration aren’t read. Use lag_tolerance and require_fresh_data_from instead.

Next steps

Turn on Paradime State

Switch to dbt™ 2.0 and set one environment variable for Bolt, the Code IDE, or both.

Configuration reference

Every setting that changes when nodes rebuild.

Read a Paradime State run

What the summary at the end of each run tells you.

Troubleshoot Paradime State

Fixes for missing summaries, unexpected rebuilds, and missed data.