dbt build selector: A Practical Guide
- Digital Hive
- May 1
- 3 min read
When you're working with dbt, especially on larger projects, you don’t always want to build every model every time. That’s where selectors come in. By grouping the models that need to be refreshed in one command time and resources are used more efficiently. With the dbt build command, selectors give you fine-grained control over exactly what gets built. In this post, we’ll break down how to use the --select and --exclude options with dbt build and how combining them can supercharge your workflow.
Before we dive in, let’s clarify a few important flags and commands:
--select and -s are interchangeable. They both define what to build.
--models is an older flag that does the same thing as --select, but it’s now considered deprecated. It still works, but it’s best to switch to --select or -s in modern dbt workflows.
--exclude defines what not to build.
The dbt list or dbt ls command will allow you to list the selected models. It is recommended to use this command to test whether the selection you use will build the models you intend to build.
A selector tells dbt which nodes (models, tests, snapshots, etc.) you want to act on. With dbt build, this means which parts of your DAG should be compiled, run, and tested.
The syntax is:
dbt build --select [selector] |
List equivalent:
dbt list --select [selector] |
You can also exclude nodes:
dbt build --select [selector] --exclude [other-selector] |
List equivalent:
dbt list--select [selector] --exclude [other-selector] |
Let’s walk through the common ways to use selectors.
1. Build a Single Model
To build just one model:
dbt build --select my_model |
This runs the model my_model, along with any relevant tests and post-hook actions.
2. Build a Model and Its Dependencies
To build a model and all of the upstream models it depends on:
dbt build --select +my_model |
The + before the model means “include all parents”.
To build a model and all of its downstream dependents:
dbt build --select my_model+ |
Want to include both upstream and downstream? Use:
dbt build --select +my_model+ |
3. Build a Whole Directory or Path
You can select all models in a specific folder:
dbt build --select path:models/staging/ |
This runs everything in models/staging/, recursively.
4. Use Tags for Logical Grouping
You can assign tags to models in your .yml or model files. Then use:
dbt build --select tag:nightly |
This is perfect for grouping models by schedule or theme.
5. Build by Resource Type
Want to build only tests or snapshots? Use:
dbt build --select resource_type:data_test dbt build --select resource_type:snapshot |
This is useful if you want to isolate part of the pipeline for debugging or CI.
6. Exclude Specific Models
To build everything except certain models:
dbt build --select tag:nightly --exclude my_model |
This is great for skipping a known-broken model or one that’s not relevant to your current work.
7. Combine Multiple Selectors
You can combine selectors using commas (,), which means OR:
dbt build --select model_a,model_b |
Use spaces for AND:
dbt build --select tag:nightly path:models/marts/ |
This will select models that match both the tag and the path.
You can also nest selectors for more control:
dbt build --select +tag:nightly+ |
8. Special Selector: state:
When using dbt in a CI/CD pipeline, you can build only what has changed:
dbt build --select state:modified --state path/to/artifacts |
This builds only models that have changed (and their children) since the last run.
9. Build All Upstream Dependencies with @
The @ selector in dbt is a powerful tool for building a model, all its downstream nodes (dependents), and all dependencies (ancestors) required by those downstream nodes. This ensures that every model needed to build any node downstream of the selected model is also refreshed.
dbt build --select @my_model |
Usecase
For example, your dashboard relies on 3 models (report_a, report_b, and report_c), and you've updated report_a. To ensure proper integration with the other two reports and their dependencies:
[stg_orders] → [report_b]
↘
[stg_customers] → [report_a] → [dashboard]
↗
[stg_products] → [report_c]
dbt build --select @report_a |
The command above will build:
report_a
Upstream models report_b, report_c, stg_customers
Ancestors of upstream models stg_orders and stg_products.
Whereas the following command:
dbt build --select +report_a |
Will build:
report_a
stg_customers
Pro Tip
When testing a new dbt build command, use dbt list or dbt ls instead. It shows which models would be affected, without running them. Example: dbt list --select my_model > build_1.txt This saves the output to a file, so you can easily compare changes across different selector versions.
Final Thoughts
Selectors are essential for managing large dbt projects efficiently. Whether you’re debugging, optimizing CI pipelines, or running targeted builds, understanding how to use --select and --exclude gives you speed and precision.
Start small, test a single model and its dependencies. Then build up with tags, paths, and more. With a little practice, you’ll be navigating complex DAGs like a pro.
Comments