dbt Tags: Grouping and Selectively Running Models
Folder structure gives you one way to group models โ by domain, by layer โ but itโs a single, fixed hierarchy. Sometimes you need a different, orthogonal grouping: every model that touches PII, every model thatโs part of the nightly-only batch, every model owned by the finance team regardless of which folder it physically lives in. dbt tags exist for exactly this โ a flexible, many-to-many way to label and select models that doesnโt require restructuring your directory layout.
Applying Tags
Tags can be set inline in a modelโs config, or centrally in dbt_project.yml for an entire folder.
-- models/finance/monthly_revenue.sql{{ config(tags=['finance', 'nightly']) }}
select ...# dbt_project.yml โ applies a tag to every model in a foldermodels: my_project: finance: +tags: ['finance']A model can have both a folder-level tag inherited from dbt_project.yml and additional tags added at the individual model level โ they combine rather than override.
Selecting by Tag
# Run every model tagged 'finance'dbt run --select tag:finance
# Run models tagged 'nightly' but exclude anything tagged 'deprecated'dbt run --select tag:nightly --exclude tag:deprecated
# Combine with graph selectorsdbt run --select tag:finance,stg_orders+This is the same selection syntax used throughout this series (covered in dbt run) โ tags are just another dimension you can select on, alongside model names and folder paths.
Common Tagging Patterns That Scale
By execution frequency, separating models that need to run every 15 minutes from ones that only need a nightly refresh:
dbt run --select tag:realtime # scheduled every 15 mindbt run --select tag:nightly # scheduled once dailyBy data sensitivity, useful for applying different access controls or masking logic to a specific subset regardless of folder:
models: - name: customer_pii_details config: tags: ['pii']# A security audit script can find every PII-tagged model instantlydbt ls --select tag:piiBy team ownership, when a project spans multiple teams and each wants to run or monitor only their own models:
dbt run --select tag:team_financedbt test --select tag:team_marketingTags vs. Folder Structure: When to Use Which
| Need | Better tool |
|---|---|
| Organizing files logically on disk | Folder structure |
| Grouping models that donโt share a folder | Tags |
| A model needs to belong to multiple groups | Tags |
| Selecting by execution schedule cadence | Tags |
A model can only live in one folder, but it can carry as many tags as make sense โ a finance model that also happens to contain PII and runs nightly can carry all three tags simultaneously, something folder structure alone canโt express.
Combining Tags With CI Pipelines
Tags are a natural way to scope different CI checks to different subsets of a large project without needing separate dbt projects.
# Example CI configurationfast_pr_check: command: "dbt build --select tag:critical_path"full_nightly_validation: command: "dbt build"A pull request check can validate only the highest-priority, fastest-to-run subset tagged critical_path, while a full nightly job validates everything โ a meaningful speed tradeoff for fast PR feedback without sacrificing full coverage entirely.
Inspecting Whatโs Tagged What
dbt ls --select tag:finance --output jsonThis lists every model carrying a given tag, useful as an audit step โ confirming that every model thatโs supposed to be tagged actually is, since a missing tag on a new model silently excludes it from whatever selective runs or checks rely on that tag.
Excluding Tags, Not Just Selecting Them
Beyond --select tag:x, --exclude is often the more precise tool when the majority of a project should run except for a small, clearly-tagged subset.
# Run everything except models still under active developmentdbt build --exclude tag:wip
# Run everything except known-expensive, rarely-needed modelsdbt build --select finance.* --exclude tag:heavy_backfill_onlyThis combination โ a broad selection with a targeted exclusion โ is often easier to maintain than an equivalently broad inclusion list, since new models added to a folder are automatically included in future runs unless explicitly tagged out, rather than needing to be manually added to an inclusion list every time.
Auditing Tag Coverage Across a Project
On a project thatโs been growing for a while, itโs worth periodically checking which models have no meaningful tags at all โ often a sign they were added before a tagging convention was established, or slipped through review.
dbt ls --output json --output-keys unique_id,tags | jq 'select(.tags == [])'This surfaces every untagged model in one pass, giving you a concrete backlog of models to bring in line with whatever tagging convention the rest of the project follows.
Common Mistakes
Relying on tags without a convention for what tags exist. Without a documented list of โthese are our tags and what each means,โ different engineers invent slightly different tag names for the same concept (fin vs finance vs Finance), fragmenting selection queries silently.
Forgetting to tag new models that should inherit a project-wide category. A tag applied at the individual model level, rather than centrally at the folder level in dbt_project.yml, is easy to forget on a newly added model โ prefer folder-level tag inheritance wherever the grouping genuinely maps to folder structure.
Using tags for something that graph selection already handles better. If you find yourself tagging every model in a folder just to select that folder, --select finance.* (a path-based selector) already does that without needing a tag at all โ tags earn their value specifically for groupings that donโt align with folder structure.
Summary
| Use case | Tag example |
|---|---|
| Execution cadence | tag:nightly, tag:realtime |
| Data sensitivity | tag:pii |
| Team ownership | tag:team_finance |
| CI scoping | tag:critical_path |
Tags give a dbt project a second, flexible axis of organization on top of folder structure โ most valuable exactly where a modelโs grouping doesnโt map cleanly onto where it physically lives in the repository.