CLI Reference
sqb build
Compile, plan, and execute the selected build lifecycle.
Compiles, plans, and executes the selected build lifecycle, running the full selected scope. Use
--no-tests and --no-audits to skip validation for fast iteration.
sqb build [SELECTOR ...] [flags]Positional SELECTOR arguments work like --select, and both forms can be combined.
Global options
Section titled “Global options”These options apply to every sqb command. --project-dir, --no-color, and --debug go
before or after the command name, as in sqb --debug build or sqb build --debug. Under
sqb dbt, put --project-dir before dbt: after it, --project-dir is passed to dbt as dbt’s
own option. --version works only directly after sqb, as in sqb --version:
| Option | Description |
|---|---|
--project-dir <path> |
Run against the project in <path> instead of the current directory |
--no-color |
Print without colour |
--debug |
Print detailed progress, the SQL each step runs, and internal diagnostics to stderr; implies --verbose |
--version, -V |
Print the SQLBuild version |
| Flag | Description |
|---|---|
--target |
Build against a configured target instead of the active/default target |
--no-tests |
Skip SQL unit tests |
--no-audits |
Skip audits |
--no-python |
Skip read-side Python tasks and assets (loader-side Python still runs for selected sources) |
--no-sql-analysis |
Disable compile-time SQL analysis (--no-sql-validation is an alias) |
--no-cache |
Bypass the reusable compile-analysis cache for this invocation |
--full-refresh |
Drop and rebuild selected models unless a model sets full_refresh false; full_refresh true forces a model even without this flag |
--changed |
Build only the selected models and seeds whose definition or inputs changed since they last succeeded; see Building only what changed |
--defer-to |
Resolve unselected model references against another target |
--defer-sources-to |
Read managed source data from another target |
--fail-fast |
Stop on first failure and skip remaining nodes |
--concurrency |
Number of worker connections (default: 1) |
--test-timeout <duration> |
Time limit for each unit test the build runs, such as 30s, or disabled; see Time limits |
--verbose, -v |
Show lifecycle SQL inline after each model |
--start-cursor |
Override the start cursor, typed from the selected incremental models’ cursor type; fails with S303 if the selection mixes timestamp and integer cursors. With no cursor model selected, an integer value is read as an integer cursor and anything else as an ISO timestamp |
--end-cursor |
Override the end cursor, typed the same way as --start-cursor |
--start-cursor-ts |
Override start cursor for timestamp incremental models (ISO format) |
--end-cursor-ts |
Override end cursor for timestamp incremental models (ISO format) |
--start-cursor-int |
Override start cursor for integer incremental models |
--end-cursor-int |
Override end cursor for integer incremental models |
--load |
Explicitly load managed sources before building |
--no-load |
Run no source loaders; selected managed sources are still audited |
--reload |
Reload managed sources (passes is_reload=True to loaders) |
--selection-diagnostics |
Warn when a selected model will build on changed upstream models that are not selected; see Selection and staleness |
--manifest |
Generate target/manifest.json with plan-aware project metadata |
SELECTOR ... |
Positional selectors, the same as --select |
--select, -s |
Select specific models, or unit tests by name (test:<name>); selecting only unit tests runs them without building models |
--exclude |
Exclude specific models |
--warehouse <name> |
Snowflake warehouse for this invocation; overrides the target’s build warehouse group and the connection warehouse |
Fast iteration
Section titled “Fast iteration”Use --no-tests and --no-audits to skip validation when you only want to materialize models:
sqb build --no-tests --no-auditsThis replaces the former sqb run command. The full lifecycle (tests + audits) is always the default; skip flags opt out of specific phases when you need speed.
Building only what changed
Section titled “Building only what changed”--changed skips each selected model or seed that would read exactly what it read the last time
it built successfully:
sqb build --changedChanged: 2 of 3 selected models and seeds run; 1 unchanged are skipped.Add --verbose to print why each one runs, such as input raw_orders changed.
A selected model or seed runs when any of these is true:
| Reason | Example |
|---|---|
| It has no successful build on record | A new model |
| Its last build did not finish | The build was killed or failed after the model started writing |
Its relation is missing, or --full-refresh or a cursor override applies |
sqb build --changed --full-refresh |
| Its definition changed | Edited SQL, config, hooks, contract or a function it calls |
| A source it reads has a different freshness value | New rows raise MAX(loaded_at) |
| An upstream model or seed was rebuilt since, or runs in this build | stg_orders ran, so customer_orders runs |
| An upstream model or seed needs to run, even when it is not selected | sqb build customer_orders --changed runs customer_orders on every build until a changed stg_orders is built |
| What it reads can’t be listed | SQL that reads relations not declared as sources or models, or a Python task or asset upstream |
A model that runs under --changed plans exactly as in a plain build: its
replay_on_change policy still decides how much
history an incremental model reprocesses. A model that runs only because an upstream was rebuilt
takes its normal incremental step.
In a scheduled job, set settings={'changed': True}. Skipped models count as successful nodes of
the run.
Every build, with or without --changed, records what each model and seed read in
_sqlbuild_consumption in its target schema, so the build needs permission to create and insert
into that table. sqb janitor keeps the newest
direct_state_history_versions builds of each relation.
Limitations:
- A source is compared only through its freshness value. A change that doesn’t move it, such as an
update that keeps the old
loaded_at, isn’t seen. A source without freshness configuration counts as changed on every build. - SQL that depends on the time, such as
current_date, or on random values never counts as changed. Build those models without--changed. - Two builds of one model less than 5 seconds apart can’t be ordered, so its downstream models run
on the next
--changedbuild.
Execution order
Section titled “Execution order”- Managed sources are loaded (unless
--no-load, which audits their existing data instead) - Selected seeds are loaded
- Source audits run before their dependent models (unless
--no-audits); with--no-load, or for a source selected by name, a source no model reads is audited at the end - SQL unit tests run before their target model (unless
--no-tests) - Models are materialized in DAG topological order
- Error-severity audits run against the staging table before promotion to the target (unless
--no-audits)
A resource with an attached audit also waits for every other model, seed, or table function that audit reads, so the audit can gate the resource like its other audits. See Audits that read other resources.
Output
Section titled “Output”Execution sqb build (concurrency: 1)
1/17 source raw__customers OK 0.05s rows=5 2/17 source raw__orders OK 0.03s rows=10
3/17 seed waffle_types OK 0.03s 7/17 view stg_orders OK 0.04s test test_stg_orders PASS expect expected stg_orders PASS expect assertion order_ids_are_not_null PASS audit not_null (order_id) PASS audit unique (order_id) PASS audit not_null (customer_id) PASS audit relationships (waffle_type_id) PASS audit accepted_values (status) PASS 13/17 table hourly_order_activity (delete_insert) OK 0.24s 5 batches (1d) range 2026-03-31T09:00:00 → 2026-04-04T14:00:00 8 rows audit (d) orders_placed_is_non_negative PASS 5/5 audit (d) not_null (activity_hour) PASS 5/5 audit (f) orders_placed_is_non_negative PASS audit (f) not_null (activity_hour) PASS
✓ Completed successfully PASS=99 WARN=0 FAIL=0 INSUFFICIENT=0 SKIP=0 TOTAL=99 (2.13s)Each resource prints one row when it finishes, followed by its tests and audits. Rows for
individual warehouse statements and for steps inside a resource, such as Create staging relation,
Promote relation, loader callable, or audit evaluation, appear only with sqb --debug build.
Without --debug, a statement that is still running after 30 seconds prints a RUNNING row every
30 seconds, with its elapsed time and, when the warehouse reports one, its query ID. A failed
statement or step still prints its FAIL row.
Deferred builds
Section titled “Deferred builds”Use --defer-to to resolve unselected model references against another target. This lets you build a subset of models in dev while referencing production tables for everything else:
sqb build fact_orders --defer-to prodNo manifest.json is required. --defer-to selects only the namespace used for unselected
references. SQLBuild resolves those relations through the active target’s sole physical
connection and never opens the deferred target’s connection. The deferred namespace must be
visible and readable through the active connection; deferral is not a cross-account,
cross-server, or cross-file transfer mechanism.
Failure behavior
Section titled “Failure behavior”When a model fails:
- Downstream models are automatically blocked and skipped
- Staging/delta tables are retained for inspection
- Failure details show the model name, failed phase, and error message
A model that exceeds its max_duration
fails with C417. The failure states the elapsed time, the limit and where it was set, whether
cancelling its running statement was confirmed, and the query IDs SQLBuild saw; downstream models are
skipped as for any other failure. Its row shows TIMEOUT. In the summary line, timed-out models and unit tests are counted under
TIMEOUT= and excluded from FAIL=
(PASS=1 WARN=0 FAIL=0 TIMEOUT=1 INSUFFICIENT=0 SKIP=1 TOTAL=3). In --json output,
summary.failure_count still includes them, and summary.timeout_count reports how many of those
failures were timeouts. A timeout is a failure for the exit code: the build exits non-zero and its
JSON status is failed.
Fingerprints
Section titled “Fingerprints”After a successful build, SQLBuild writes version identities to _sqlbuild_fingerprints in the target schema. These are used on subsequent runs to detect changes and skip unchanged work. A build writes a row only for a resource whose identity differs from its latest row, so a build that changes no definitions writes none. In a project with model migration history, every build writes a row for each resource it builds. See Planning and Change Detection for details.
Runtime artifacts
Section titled “Runtime artifacts”Build writes executed lifecycle SQL to target/run/models/. These files contain the actual SQL that was executed, including resolved cursor bounds and runtime substitutions.