Even if you know the commands, choosing between run and build during reviews or pre-production validation can get confusing. Real-world work demands fast iteration, CI needs reliable consistency, and the exam tests precise definitions.
This article follows the dbt official documentation to summarize the differences, how to choose, and how related features (selectors, incremental models, snapshots, tests) work together.
dbt run targets models only. It compiles and executes the nodes specified by the selector. Tests do not run. Dependencies affect execution order, but unselected parent models are not automatically re-run (and missing parents cause a reference error).
dbt build runs the seeds, snapshots, and models within the selected scope in dependency order, and then runs the related tests (schema and data tests). In other words, it is a unified flow that builds and validates in a single command.
| Command | Purpose | Targets | Dependency Order |
|---|---|---|---|
| dbt run | Run models | models only | Runs in ref order, but unselected parents are not run by default |
| dbt build | Build and validate in one go | seeds, snapshots, models + tests | Runs everything in DAG order |
Execution flow of run vs build (conceptual)
Minimal example: single model vs integrated build
# Single model only (explicitly include parents with +)
dbt run -s +stg_orders
# Build and test the selected scope together
# Targets changed nodes and their downstream, plus related tests
dbt build -s state:modified+dbt controls parallelism and ordering based on the DAG. With build, tests tied to a node run only after that node finishes building. Tests for unselected nodes do not run.
When a test fails, the failure is recorded and other independent nodes continue running by default (use --fail-fast to stop early). Since run does not execute tests, failure detection depends on running test separately.
| Aspect | dbt run | dbt build |
|---|---|---|
| When tests run | Never (separate command) | After each node is built |
| Default behavior on failure | The branch with the failed model stops; other branches may continue | Same as above; test failures are aggregated as failures |
| Option to stop early | --fail-fast (applies to both run and test) | --fail-fast |
Execution sequence of nodes and tests
Examples of schema and data tests
# models/schema.yml (generic test example)
models:
- name: dim_customers
columns:
- name: customer_id
tests:
- not_null
- unique
# tests/assert_positive_revenue.sql (singular test example)
-- A failure is aggregated as a build failure
select 1 where exists (
select 1 from {{ ref('fct_revenue') }} where total_revenue < 0
);
# Run
# Executes schema and data tests against fct_revenue and dim_customers
dbt build -s dim_customers fct_revenueFor both run and build, selectors decide what gets targeted. The basics: include parents/children with +, pick by attribute with tag:, and capture change impact with state:.
With build, the difference is that tests are automatically attached to the selected scope. Tests bound to unselected nodes are not executed.
| Selector | Meaning | Typical Use |
|---|---|---|
| +stg_orders | stg_orders and its upstream | Verify together with referenced dependencies |
| state:modified+ | Changed nodes and their downstream | Impact-area testing for PR/CI |
| tag:nightly | Assets tagged nightly | Limit targets for the nightly batch |
Scope differences by selector
A -> B -> C
-s B : [B]
-s +B : [A, B]
-s B+ : [B, C]
-s +B+ : [A, B, C]Using the same selector for run and build
# Development loop (models only, fast)
dbt run -s +stg_orders
# CI (build and validate the impact area)
dbt build -s state:modified+ --defer --state target/manifestWhen selected, incremental models apply the delta in their default mode, while --full-refresh forces a full recompute. The behavior is identical under run or build.
Snapshots are independent nodes; once referenced, they are wired into the DAG. Because build can include snapshots in scope, it is well suited to integrated validation of models that depend on snapshots.
| Target | Points common to run/build | Cautions |
|---|---|---|
| Incremental model | Apply delta; --full-refresh fully recomputes | Misconfigured keys or unique_key can silently produce duplicates |
| snapshot | If selected, build executes and validates it | Make schedules and dependencies explicit; avoid full-table comparisons every time |
Dependency between a snapshot and a model
Configuration example: incremental and snapshot
# models/fct_orders.sql
{{ config(materialized='incremental', unique_key='order_id') }}
select * from {{ ref('stg_orders') }}
{% if is_incremental() %}
where updated_at > (select max(updated_at) from {{ this }})
{% endif %}
# snapshots/customers.sql
{% snapshot customers_scd %}
{{ config(strategy='timestamp', unique_key='customer_id', updated_at='updated_at') }}
select * from {{ source('app', 'customers') }}
{% endsnapshot %}
# Run
# Build and validate including the impact area
dbt build -s +dim_customers
# Full recompute (plan it carefully)
dbt run -s fct_orders --full-refreshFor PR validation and pre-production consistency checks, dbt build is the first choice. It covers build and tests in one shot, so failures are detected early.
For local development and debugging, iterate quickly with dbt run on the smallest possible scope, and once the design lands, run build to also clear the tests. That is the most efficient flow.
| Scenario | Recommended Command | Reason |
|---|---|---|
| Local development | dbt run -s +target | Prioritize iteration speed with a minimal scope |
| PR/CI | dbt build -s state:modified+ --defer | Guarantee both build and test of change impact in one go |
| Pre-production rehearsal | dbt build | Comprehensive validation equivalent to production |
A typical CI pipeline
Minimal GitHub Actions job example
jobs:
dbt-ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install dbt-core dbt-bigquery # pick the adapter you need
- run: dbt deps
- run: dbt build -s state:modified+ --defer --state targetThe exam tests strict definitions. In particular, lock in what dbt build targets, when tests run, and how unselected nodes are handled.
In practice, over- or under-selecting and overusing full-refresh cause cost spikes, locking, and false positives. Avoid them with rules and automation.
| Common Misconception | Correct Understanding | What to Do |
|---|---|---|
| build always runs every test | Only tests bound to the selected scope are executed | Make the scope explicit with -s/-x |
| Selecting a child model auto-runs the parent | Parents are not re-run unless selected | Use + to include dependencies |
| run and build have the same speed | build takes longer by the time the tests need | Use run for development and build at gates |
Decision branches
Exam mini-check (self-quiz)
- dbt run: what runs? models only
- dbt build: what runs? seeds/snapshots/models + tests
- When do tests run? after the target node is built
- Include parents/children? extend the scope with +Analytics Engineer
問題 1
A developer creates a PR and wants to automatically build the changed models and their downstream while also running related tests. Which command is the most concise and appropriate?
正解: C
dbt build runs seeds/snapshots/models in DAG order and then runs the tests bound to those nodes. state:modified+ targets the changes and their downstream, giving the shortest path for PR/CI. run does not execute tests.
If a test fails during dbt build, does the model artifact get rolled back?
By default, no. The model run still succeeds and the subsequent test simply records the failure. If you need rollback semantics, design the transaction settings or workflow to clean up on failure.
How do I exclude only some of the heavier tests from dbt build?
Use a selector to exclude them. For example: dbt build -s +mart_orders -x test_type:data. In practice, tagging the heavy tests and excluding them with something like -x tag:heavy_test works best.
How do I minimize the speed gap between dbt run and dbt build?
Narrow the scope with selectors and tune parallelism (--threads). Strategically, run heavy tests on a nightly tag, keep schema tests in every cycle, and isolate data tests as batched runs.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
dbt Models: SQL-Defined Transformation Units (2026)
Model fundamentals — SELECT-based definitions, naming, refs,...
dbt Analytics Engineering Exam: Complete Guide (2026)
Pass the AE Certification — scope, weighting, sample questio...
dbt Cloud vs dbt Core: Feature & Cost Comparison (2026)
Honest comparison of dbt Cloud vs. dbt Core — IDE, scheduler...
dbt Project Structure: models/seeds/macros Layout (2026)
Recommended dbt project layout — models, seeds, macros, snap...
dbt_project.yml Explained: Every Config (2026)
Every dbt_project.yml setting that matters — paths, vars, ma...