sqb dbt build or sqb dbt run, SQLBuild plans which dbt models actually need to run instead of rebuilding everything in the selection. Models whose SQL has not changed and whose inputs are current are pruned from the dbt command, so a second build skips them entirely.
This works on a plain dbt project, with no SQLBuild models and no changes to your dbt files. SQLBuild reads the dbt manifest, compares it against state it stores in your warehouse, and decides per model whether dbt needs to run it.
How dbt models are tracked
SQLBuild stores a fingerprint for every dbt model it builds, in a_sqlbuild_fingerprints table in your target schema. Each fingerprint is keyed with node_type: "dbt" and the model’s dbt unique_id, and records the model’s version identity.
The version identity comes from dbt’s own checksum for the model node in the manifest. On each plan, SQLBuild compares the checksum in the current manifest against the fingerprint it last stored:
| Condition | Action | Reason |
|---|---|---|
| No stored fingerprint | run | first run |
| Target relation missing | run | relation missing |
| Manifest checksum differs from stored fingerprint | run | checksum changed |
| Full refresh requested | run | full refresh |
| Everything matches and relation exists | skip | no change |
What SQLBuild creates in your warehouse
All state is append-only and lives in your target schema, in the same warehouse dbt already uses. There is no external state store, no manifest comparison server, and no requirement to log in anywhere. SQLBuild creates two small tables:| Table | Contents |
|---|---|
_sqlbuild_fingerprints | One row per build per model, recording its version identity. Drives change detection. |
_sqlbuild_source_freshness | One row per build per source, recording the last observed freshness. Drives source-change detection. |
Cascade propagation
Change detection runs over the combined dbt and SQLBuild graph, so a change in one dbt model correctly forces the work that depends on it, in both directions:- Upstream changed. A dbt model that is otherwise current is rerun when any of its upstream dbt models is running. The plan reason is
upstream_changed. - Downstream into SQLBuild. When a dbt model runs, SQLBuild marks the SQLBuild models that read from it (through
__dbt_ref) as stale, so they rebuild against the new data.
Source freshness
SQLBuild translates the sources declared in the dbt manifest into its own source freshness model and observes them as part of planning. Observations are stored in the_sqlbuild_source_freshness table in your target schema.
- Source changed. A current dbt model whose upstream source has new data is promoted to run, with reason
source_freshness_changed. - Source stale past its age policy. If an upstream source is older than its configured age tolerance, the dbt models downstream of it are blocked rather than built on stale inputs, with reason
source_freshness_error. SQLBuild models downstream of a blocked dbt model are blocked too.
Pruning and steady state
Only the dbt models classified asrun are passed to the underlying dbt build/dbt run command. Current models are removed from the dbt selection, dbt tests and seeds for pruned models are dropped from the command, and dbt never sees the models it does not need to rebuild.
When every dbt model in the selection is current, SQLBuild does not invoke dbt at all. The dbt section of the plan reports the skip and lists the current models:
Replay on change
When a changed incremental dbt model is rerun,replay_on_change controls whether it runs incrementally or rebuilds in full. It is a single project-wide policy in the [dbt] config block, applied to every changed model in the run (not per model):
| Value | Behavior |
|---|---|
forward_only (default) | Changed models run incrementally, picking up new data from where they left off. |
full | Changed models are rebuilt in full. SQLBuild adds --full-refresh to the dbt run when there is model work to do. |
replay_on_change, the dbt setting is all-or-nothing across the run and does not support bounded windows. A bounded-<duration> value is rejected for dbt.
What is never touched
- dbt source files are never modified. SQLBuild reads the manifest and drives the
dbtCLI; it does not patch, rewrite, or revert your dbt project. - dbt internals are never monkey-patched. Selection and execution go through the documented
dbtCLI surface (dbt ls,dbt compile,dbt build/dbt run). - State lives in your warehouse, not in a separate database or service.

