Home / Data Platform / dbt & Quality

Data PlatformCheat sheetBeginner

dbt node selection and CLI cheat sheet: run exactly what you mean

The dbt selectors, graph operators and CLI flags you need on support duty to rebuild one model, its downstream, only what changed, or only what failed.

Deepak Bhardwaj7 min read

Applies todbt Core 1.7+ (notes for 1.8 and 1.9 features), dbt Cloud CLI, any adapter

Why this matters on call

Most dbt incidents end with "rebuild the broken model and everything that depends on it, and nothing else". Getting the selector wrong either misses a downstream table (stale data on a dashboard) or rebuilds the whole project during business hours (warehouse cost and lock contention). Check the selection with dbt ls first, then run it.

dbt ls --select <selector> --resource-type model --output name

Tip

Always preview with dbt ls before dbt run --full-refresh or any command that targets production. It parses the project without touching the warehouse.

Graph operators

Selector Selects
orders The orders node only
orders+ orders and everything downstream
+orders orders and everything upstream
+orders+ Upstream, the node and downstream
orders+1 orders and its direct children only
2+orders orders and two generations of parents
@orders orders, its descendants, and all ancestors of those descendants (safe for CI builds of a changed model)

Selection methods

Selector Selects
path:models/staging/stripe or models/staging/stripe Everything under a folder
tag:nightly Nodes tagged nightly
source:stripe+ Everything that reads from the stripe source
source:stripe.charges+ Downstream of one source table
config.materialized:incremental All incremental models
resource_type:snapshot All snapshots
test_type:generic / test_type:singular Generic (YAML) or singular (SQL file) tests
package:dbt_utils Nodes from one package
exposure:weekly_sales+, +exposure:weekly_sales Nodes feeding a dashboard or exposure (use + before to get parents)
state:modified / state:new Changed or added since the artifacts in --state
result:error, result:fail, result:warn Nodes with that status in the previous run's run_results.json

Method names vary slightly by version; dbt ls --help and the selection docs for your version are the source of truth.

Union, intersection and exclusion

# Union: space-separated
dbt run --select tag:finance tag:sales

# Intersection: comma, no spaces
dbt run --select tag:nightly,config.materialized:incremental

# Exclude
dbt build --select models/marts --exclude tag:deprecated orders_legacy

Quote selectors in PowerShell and zsh if they contain + or *, for example --select "orders+".

Common support tasks

Goal Command
Rebuild one broken model and its downstream, with tests dbt build --select orders+
Rebuild only what failed last run dbt retry (1.6+)
Rebuild failed nodes and their children from saved artifacts dbt build --select result:error+ result:fail+ --state target/
Full refresh one incremental model dbt run --select orders --full-refresh
Run against a non-default target dbt build --select orders+ --target prod
Pass variables dbt run --select orders --vars '{"run_date": "2026-10-23"}'
Stop on the first failure dbt build --select marts --fail-fast
Limit concurrency to protect the warehouse dbt build --select marts --threads 4
Check source freshness dbt source freshness --select source:stripe
Test only, no model builds dbt test --select orders
Look at rows a model produces, without building it dbt show --select orders --limit 20
Run ad-hoc SQL through the project's connection dbt show --inline "select count(*) from {{ ref('orders') }}"
See the compiled SQL dbt compile --select orders then open target/compiled/...
Run a macro (grants, cleanup) dbt run-operation grant_select --args '{"role": "reporter"}'

Warning

--full-refresh drops and rebuilds incremental models and reloads seeds. On a large fact table this can take hours and leaves the table empty or locked while it runs, depending on the adapter. Confirm the time window with the data owner and run it against one model, not a folder.

dbt retry vs result selectors

dbt retry reads target/run_results.json and re-runs the failed command from the point of failure with the same flags. It only works if target/ from the failed run is still there, so in CI or orchestrators that use a fresh container, persist the artifacts or use result:error+ --state <path> against a saved copy.

Slim CI and deferral

Build only what changed in a pull request, reading unchanged parents from production:

# prod-artifacts/ contains manifest.json from the last production run
dbt build --select state:modified+ --defer --state prod-artifacts/

# Prefer the production version of unchanged nodes even if a dev copy exists
dbt build --select state:modified+ --defer --favor-state --state prod-artifacts/

# 1.6+: clone unchanged production models into the CI schema (zero-copy where the adapter supports it)
dbt clone --select state:unmodified --state prod-artifacts/

state:modified includes sub-selectors such as state:modified.body, state:modified.configs and state:modified.relation when you need to narrow it.

1.8+ and 1.9+ helpers

# 1.8+: build schema only, with zero rows, to catch SQL and contract errors cheaply
dbt build --select state:modified+ --empty

# 1.9+: reprocess a window of a microbatch incremental model
dbt run --select orders --event-time-start "2026-10-20" --event-time-end "2026-10-23"

Check dbt --version before relying on these; older versions reject the flags.

Tests and indirect selection

When you select a model, dbt also selects tests attached to it. --indirect-selection controls tests that touch several models (for example a relationships test):

Value Behaviour
eager (default) Run the test if any of its parents is selected
cautious Run only if all parents are selected
buildable Run if all parents are selected or are ancestors of the selection
empty Don't select tests indirectly
dbt build --select orders --indirect-selection cautious

Use cautious when a partial rebuild keeps failing a relationship test against a table you didn't rebuild.

Saved selectors

Put production selections in selectors.yml so the orchestrator and on-call use the same definition:

selectors:
  - name: nightly_finance
    description: Nightly finance marts, without deprecated models
    definition:
      union:
        - method: tag
          value: finance
          children: true
        - exclude:
            - method: tag
              value: deprecated
dbt ls --selector nightly_finance --output name
dbt build --selector nightly_finance

Debugging flags

Flag Use
dbt debug Check profile, connection and dependencies
--debug or --log-level debug Full SQL and adapter messages on the console
--warn-error Treat warnings as errors (CI)
dbt ls --output json --output-keys "name resource_type config" Inspect node configs without opening YAML
dbt parse Parse only; catches YAML and Jinja errors fast

logs/dbt.log and target/run_results.json hold the details for every run. For specific error messages, see dbt run failures.

Prevent it next time

  • Tag models by schedule and owner (tag:nightly, tag:finance) so selections stay short and readable.
  • Keep production selections in selectors.yml, not hand-typed in orchestrator configs.
  • Save manifest.json and run_results.json from every production run; slim CI, dbt retry and incident review all depend on them.
  • Add dbt ls of the planned selection to change tickets that involve --full-refresh.