dbt: CLI Reference
Quote
“Make it work, make it right, make it fast.”
Source: Kent Beck
Summary
Explains the dbt command-line interface as an operational reference for running, testing, compiling, selecting, cleaning, and debugging models, with an emphasis on state-aware selection and CI-friendly execution patterns for a production warehouse project.
Core dbt commands
- Covers
dbt run,dbt test,dbt build,dbt compile,dbt debug,dbt deps,dbt seed,dbt snapshot, docs commands, source freshness checks, node listing, cleanup, and retry behavior- Connects each command to what it changes in the warehouse or project state so the CLI can be used intentionally instead of as a memorized list of verbs
Selection and state-aware execution
- Explains selector syntax, graph operators, set operators, and key flags such as
--select,--exclude,--vars,--threads,--full-refresh,--defer, and slim-CI state selection- Shows how node selection and deferred state turn the CLI into a precise execution surface for local debugging, targeted reruns, and CI optimization
Output interpretation and operating patterns
- Covers reading CLI output, using debug and compile as preflight tools, and distinguishing build-versus-run/test behavior so failures are localized to the right layer faster
- Emphasizes CI/CD-oriented command choices that reduce unnecessary work and prevent downstream models from running after upstream failures
Operations and safety
- Warnings: running broad selectors against the wrong target, misunderstanding
buildversusrun && test, rebuilding incrementals unintentionally, and using state or defer flags without the correct artifact context- Recommendations: default to the narrowest selector that answers the question, use
dbt debuganddbt compilebefore expensive runs, preferdbt buildin CI, and treat selector syntax as a control surface rather than a convenience shortcut
Glossary
dbt run
The CLI command that materializes selected models into the warehouse.
It matters here because it is the direct execution entry point for most model builds and the baseline against which other commands are compared.
Writes warehouse state
dbt runchanges relations in the active target. A broad selector or wrong target can materialize far more than intended.
dbt test
The CLI command that executes schema and singular tests against selected resources.
It matters here because testing is a separate execution surface from model builds, and understanding that separation is essential when debugging failures.
Assertion layer
dbt testvalidates data properties after relations exist. It does not replace compile-time validation or warehouse execution checks.
dbt build
A composite command that runs seeds, snapshots, models, and tests in DAG order.
It matters here because it is the preferred CI entry point when upstream failure should stop downstream work automatically.
More than run plus test
dbt buildis not just a convenience wrapper. Its DAG-aware execution semantics make it safer for CI than chainingrunandtestmanually.
dbt compile
The CLI command that renders Jinja into pure SQL without executing anything in the warehouse.
It matters here because compile is the fastest way to isolate Jinja and graph problems before burning warehouse time.
Cheap preflight check
Compile failures point to dbt or Jinja layers, not warehouse runtime. Use it early when the question is “will this render” rather than “will this execute.”
dbt debug
The CLI command that validates project parsing, profile selection, and warehouse connectivity.
It matters here because many runtime failures are really target or credential problems that
dbt debugcan expose before a real run starts.Connection before execution
If
dbt debugis red, later model failures are often misleading noise. Fix profile and auth issues before troubleshooting model SQL.
dbt deps
The CLI command that installs packages declared in
packages.yml.It matters here because package macros and tests change project behavior, and stale dependencies often explain missing macro or test-name errors.
Project behavior depends on it
A project that compiles on one machine can fail on another if package versions differ. Treat
depsas part of environment setup, not as optional cleanup.
dbt seed
The CLI command that loads CSV files from
seeds/into warehouse tables.It matters here because seeds are operational warehouse writes, and they often participate in CI, reference data bootstrapping, or environment setup.
Reference data loader
Seeds are ideal for small, versioned lookup data. They are not a substitute for real ingestion pipelines or bulk data movement.
dbt snapshot
The CLI command that executes snapshot definitions to record historical changes over time.
It matters here because snapshots change persistence and history semantics compared with ordinary model runs.
History accumulates
Snapshot runs add or update historical state rather than rebuilding a simple relation. Run them with the same care you would apply to any temporal data process.
Node selection
The dbt selector system that chooses which resources commands act on, using model names, paths, tags, graph operators, and state expressions.
It matters here because nearly every CLI command becomes safe or dangerous based on selector scope.
Scope is the real command
In practice,
dbt runwithout the right selector is a different operation fromdbt run --select .... Precision comes from selection more than from the base verb.
Graph operator
A selector modifier such as
+that expands selection to upstream parents, downstream children, or both.It matters here because graph operators are what turn a single node into a dependency-aware subgraph execution.
Expansion grows fast
One extra
+can change a local debug run into a large warehouse operation. Always read graph-expanding selectors as blast-radius multipliers.
State selection
A selector mode that compares the current project to a saved set of artifacts and chooses only changed resources, often with
state:modified+.It matters here because state-aware selection is one of the main ways teams keep CI fast in larger dbt projects.
Artifacts must match reality
State selection is only trustworthy when the referenced artifacts really represent the comparison environment you think they do, such as the last production manifest.
--defer
A dbt flag that lets unresolved upstream references point at objects from another environment’s artifacts instead of rebuilding everything locally.
It matters here because slim CI and environment-aware testing often depend on deferring unchanged parents to production state.
Environment substitution is intentional
--deferchanges what relation a ref resolves to. That is powerful, but only if the artifact source and target environment are explicit and trustworthy.
--full-refresh
A flag that forces dbt to rebuild incremental models from scratch instead of using their incremental logic.
It matters here because it is one of the highest-cost and highest-impact CLI switches in normal dbt operation.
Expensive by design
Full refresh is the right fix for some drift and schema changes, but it can be costly and disruptive on large fact models if used casually.
dbt ls
The CLI command that lists resources matching a selector without executing them.
It matters here because it is the safest way to validate selector scope before running a command that mutates warehouse state.
Dry-run for selection logic
If you are unsure what a selector will hit, inspect it with
dbt lsfirst. It is often the fastest way to prevent an unnecessarily broad run.
dbt retry
The CLI command that re-runs the last failed invocation.
It matters here because retry is useful operationally, but only when you understand what previous state and selection it is actually replaying.
Context matters
Retry saves time only when the previous invocation context is still valid. If the target, code, or upstream state has changed, a fresh scoped command is usually safer.
Core Commands Overview
| Command | What it does |
|---|---|
dbt run | Materialise models |
dbt test | Execute schema and singular tests |
dbt build | run + test + seed + snapshot in DAG order |
dbt compile | Render Jinja → SQL, write to target/compiled/ |
dbt debug | Validate connection and config |
dbt deps | Install packages from packages.yml |
dbt seed | Load CSV seeds into the warehouse |
dbt snapshot | Execute snapshot blocks |
dbt docs generate | Build the documentation manifest |
dbt docs serve | Serve docs on localhost:8080 |
dbt source freshness | Check source table staleness |
dbt ls | List nodes matching a selector |
dbt clean | Delete target/ and dbt_packages/ |
dbt retry | Re-run the last failed invocation |
dbt run
Materialise one or more models into the warehouse.
These dbt run examples show how selector scope, state artifacts, and execution flags change the blast radius of a warehouse write.
# Run everything
dbt run
# Run a single model
dbt run --select stg_market_data__daily_prices
# Run a model and all its downstream dependants
dbt run --select stg_market_data__daily_prices+
# Run a model and all its upstream parents
dbt run --select +fct_index_performance
# Run a model with both parents and children
dbt run --select +fct_index_performance+
# Run all models in a directory
dbt run --select staging/market_data
# Run models with a specific tag
dbt run --select tag:daily
# Run only models modified since the last production run (state-aware)
dbt run --select state:modified+ --state ./prod_artifacts
# Exclude a subtree
dbt run --select marts/ --exclude fct_composite_scores
# Pass runtime variables
dbt run --select fct_index_performance --vars '{"lookback_days": 7}'
# Target a non-default environment
dbt run --target prod
# Parallelism
dbt run --threads 8
# Stop immediately on first failure (CI-friendly)
dbt run --fail-fast
# Full refresh of an incremental model (rebuild from scratch)
dbt run --select fct_index_performance --full-refreshdbt test
These dbt test examples narrow execution by layer, model, and test type so data-quality checks stay targeted and cheap.
# Test everything
dbt test
# Test only models in the performance mart
dbt test --select marts/performance
# Test a single model
dbt test --select fct_index_performance
# Test only schema (YAML-defined) tests
dbt test --select test_type:generic
# Test only singular (custom SQL) tests
dbt test --select test_type:singular
# Run tests tagged "critical"
dbt test --select tag:critical
# Store failed rows in the warehouse for inspection
dbt test --store-failures
# Continue even after failures (collect all results)
dbt test --no-fail-fastdbt build
dbt build is the recommended command for CI/CD. It runs seeds, snapshots, models, and tests in DAG-topological order, so a model is tested before its downstream models execute.
These dbt build examples cover full runs, slim CI selection, and broad rebuild scenarios that should be used deliberately.
# Full build
dbt build
# Build only the ESG subgraph
dbt build --select +fct_composite_scores
# Build only changed nodes and downstream (slim CI pattern)
dbt build --select state:modified+ --defer --state ./prod_artifacts
# Validate the selected graph without reading full source volumes
dbt build --empty --select +fct_index_performance
# Build with full refresh for incremental models
dbt build --full-refresh --select tag:incrementalBuild vs run plus test
dbt buildguarantees that ifstg_esg__scorestests fail, the downstreamint_esg_normalizedwill never execute.dbt run && dbt testruns all models first, so failures propagate into downstream data before you discover them.
Use
--emptyfor cheap graph validationCurrent dbt docs expose
dbt build --emptyas a schema-only dry run. It still compiles and executes selected models against the warehouse, but it limits refs and sources to zero rows so you can validate dependency wiring and relation creation logic without paying for full input scans.
dbt compile
Renders Jinja templates to plain SQL without executing anything. Useful for debugging macro output.
These compile examples render model SQL into the target artifacts directory so you can inspect the exact statement dbt plans to run.
# Compile everything
dbt compile
# Compile one model and inspect the output
dbt compile --select int_daily_returns
# Output written to: target/compiled/financial_platform/models/intermediate/market_data/int_daily_returns.sqldbt debug
Validates that dbt can connect to the warehouse and that dbt_project.yml parses correctly.
dbt debug checks profile resolution, target selection, adapter connectivity, and project parsing before you spend time on a real build.
dbt debug
# Checks: profiles.yml location, profile/target names, adapter connection,
# dbt_project.yml validity, package versionsdbt deps
Installs packages declared in packages.yml.
Run dbt deps before compilation when package versions or macros may have changed between environments.
dbt depsThis packages.yml example pins dependency ranges so installs stay within a reviewed compatibility window instead of drifting to arbitrary major versions.
# packages.yml
packages:
- package: dbt-labs/dbt_utils
version: [">=1.1.0", "<2.0.0"]
- package: calogica/dbt_expectations
version: [">=0.10.0", "<1.0.0"]
- package: dbt-labs/audit_helper
version: [">=0.11.0", "<1.0.0"]dbt seed
Loads CSV files from the seeds/ directory into the warehouse.
These seed commands cover routine loads and the rebuild path you need after a schema change or corrected reference file.
# Load all seeds
dbt seed
# Load a specific seed
dbt seed --select ref_gics_sectors
# Force drop-and-recreate (useful after schema change)
dbt seed --full-refreshTypical seeds for a financial platform:
| Seed | Purpose |
|---|---|
ref_gics_sectors.csv | GICS sector / industry hierarchy |
ref_currency_codes.csv | ISO 4217 currency codes and FX flags |
ref_index_metadata.csv | Index names, base dates, provider codes |
ref_trading_calendar.csv | Exchange trading days (holiday overrides) |
dbt snapshot
Executes snapshot definitions to capture SCD Type 2 history.
These snapshot commands run either the full snapshot set or a named temporal capture when you need to isolate one history-bearing resource.
# Run all snapshots
dbt snapshot
# Run a specific snapshot
dbt snapshot --select snap_index_constituentsThis snapshot definition tracks row history by timestamp and invalidates hard deletes so point-in-time analyses can distinguish active from retired records.
-- snapshots/snap_index_constituents.sql
{% snapshot snap_index_constituents %}
{{ config(
target_schema = 'snapshots',
unique_key = 'constituent_key',
strategy = 'timestamp',
updated_at = 'updated_at',
invalidate_hard_deletes = true
) }}
select
{{ dbt_utils.generate_surrogate_key(['index_id', 'security_id']) }} as constituent_key,
index_id,
security_id,
weight,
effective_date,
updated_at
from {{ ref('stg_market_data__index_constituents') }}
{% endsnapshot %}dbt docs
These docs commands generate the catalog artifacts first and then optionally serve the site locally for model and lineage review.
# Generate the docs site (writes to target/catalog.json + manifest.json)
dbt docs generate
# Serve locally (default port 8080)
dbt docs serve
# Serve on a custom port
dbt docs serve --port 9090Documentation is pulled from description: fields in .yml files and rendered with lineage graphs. Every model, source, column, and test is searchable.
dbt source freshness
Checks whether source tables have been updated within the configured freshness window.
These freshness commands cover default monitoring, scoped source checks, and artifact output for downstream alerting systems.
# Check all sources
dbt source freshness
# Check sources in the market_data source group only
dbt source freshness --select source:market_data
# Write results to a JSON file (useful for alerting pipelines)
dbt source freshness --output target/sources.jsonExit codes: 0 = pass, 1 = warn, 2 = error. Wire 2 into your alerting system.
dbt ls (list)
List DAG nodes without executing anything.
dbt ls is the safest way to confirm selector scope before you run a command that writes warehouse state.
# List all models
dbt ls --resource-type model
# List models in the marts layer
dbt ls --select marts/
# List all tests for a specific model
dbt ls --select stg_market_data__daily_prices --resource-type test
# List models that would be affected by a state:modified selector
dbt ls --select state:modified+ --state ./prod_artifacts
# Output as JSON for scripting
dbt ls --output json --select tag:dailydbt clean
Deletes compiled artifacts and installed packages. Run before a fresh dbt deps.
dbt clean removes generated artifacts so you can force a dependency reinstall or clear stale compiled output.
dbt clean
# Deletes: target/, dbt_packages/dbt retry
Re-runs the last failed invocation using the same selection and flags. Useful in CI when a transient network error causes a single model failure.
dbt retry only helps after a prior run has already executed nodes and written run results for dbt to replay from the point of failure.
dbt retryInternally, dbt reads target/run_results.json and re-queues all nodes that did not have status success.
Retry can be a no-op
If the failed command stopped before any nodes executed,
dbt retryhas nothing useful to replay and will not rebuild the graph for you. Fix the root cause, inspecttarget/run_results.jsonif needed, and rerun the scoped command explicitly when the previous failure happened before execution started.
Node Selection Reference
Selector Syntax
| Syntax | Meaning |
|---|---|
model_name | Exact model name |
+model_name | Model + all ancestors |
model_name+ | Model + all descendants |
+model_name+ | Model + ancestors + descendants |
model_name+2 | Model + 2 levels downstream |
path/to/dir | All models under that directory |
tag:tagname | Models with that tag |
source:source_name | Source nodes |
source:source_name.table_name | Specific source table |
config.materialized:incremental | Models with a config property |
state:modified | Nodes changed vs —state artifacts |
state:modified+ | Changed nodes + their downstream |
state:new | Nodes that didn’t exist in —state |
exposure:exposure_name | All models feeding an exposure |
metric:metric_name | All models feeding a metric |
Set Operators
These selector combinations show how dbt unions, intersects, and subtracts resource sets before execution.
# Union: run both subgraphs
dbt run --select staging/market_data staging/esg
# Intersection: models that match both selectors
dbt run --select "tag:daily,config.materialized:incremental"
# Difference (exclude)
dbt run --select marts/ --exclude fct_composite_scores+Key Flags Reference
| Flag | Commands | Purpose |
|---|---|---|
--select / -s | all | Node selector |
--exclude | all | Subtract nodes from selection |
--full-refresh | run, build | Drop and recreate incrementals |
--vars | run, test, build | Pass {key: value} dict as JSON string |
--target / -t | all | Override profile target |
--threads | run, test, build | Parallelism (overrides profile) |
--fail-fast | run, test, build | Halt on first failure |
--store-failures | test, build | Persist failed rows to warehouse |
--defer | run, build | Use prod artifacts for unselected parents |
--state | run, build, ls | Path to production artifacts directory |
--no-partial-parse | all | Force full re-parse of project |
--profiles-dir | all | Override default ~/.dbt location |
--project-dir | all | Override project root directory |
—defer and Slim CI Pattern
--defer lets developers run only their changed models in a dev environment, resolving unselected upstream ref() calls against the production schema instead of rebuilding everything.
This slim-CI pattern combines state comparison, deferral, and an explicit target so changed nodes reuse trusted upstream production objects.
# 1. In CI: download prod manifest
dbt run --target prod --select ... # or download from artifact storage
# 2. In feature branch CI job:
dbt build \
--select state:modified+ \
--defer \
--state ./prod_artifacts \
--target devThis means a developer who only changes int_esg_normalized does not need to rebuild all of stg_esg__scores — dbt will resolve that ref against the production view.
Reading CLI Output
This sample log shows the sequence dbt prints as it discovers nodes, executes them, and summarizes the final pass, warning, error, and skip counts.
Running with dbt=1.8.0
Found 42 models, 18 tests, 4 seeds, 2 snapshots, 5 sources
Concurrency: 8 threads (target='dev')
1 of 42 START sql view model silver.stg_market_data__daily_prices ......... [RUN]
1 of 42 OK created sql view model silver.stg_market_data__daily_prices ..... [OK in 1.23s]
...
14 of 42 START sql incremental model gold.fct_index_performance ............ [RUN]
14 of 42 OK created sql incremental model gold.fct_index_performance ........ [OK in 8.47s]
...
Finished running 42 models in 0 hours 2 minutes and 11.38 seconds (131.38s).
Completed successfully.
Done. PASS=42 WARN=0 ERROR=0 SKIP=0 TOTAL=42| Status | Meaning |
|---|---|
OK | Model materialised successfully |
ERROR | SQL execution failed |
SKIP | Skipped because an upstream node failed |
WARN | Test severity=warn threshold crossed |
PASS | Test passed |
FAIL | Test failed (severity=error) |
Skip propagation
A single
ERRORin a staging model willSKIPall downstream intermediates and marts. Always check the first error in the log because it is usually the root cause.
Isolate the root cause before rerunning
Scroll to the first
ERRORentry in the log. SubsequentSKIPlines are consequences, not causes. Fix the root model, then usedbt retryto re-run only the failed and skipped nodes without rebuilding the whole graph. In CI, usedbt run --fail-fastto stop immediately and surface the root error clearly.