# Working with Tags

Tags in dbt are powerful metadata labels that can be applied to various resources in your project. They enable flexible model selection, improved workflow management, and better project organization.

### What Are Tags?

Tags are simple text labels you can assign to models, sources, snapshots, and other dbt resources. They help you organize, categorize, and select specific subsets of your project for execution or documentation.

By leveraging tags, you can:

* **Group models logically** – Categorize models based on refresh schedule, function, or ownership
* **Control execution** – Run or exclude specific sets of models
* **Optimize CI/CD pipelines** – Target models for incremental builds and tests
* **Improve project maintainability** – Standardize workflows across teams

***

### How to Apply Tags

Tags can be applied in two primary ways: directly in model files or in your project configuration file.

#### 1. Defining Tags in a Model File

Tags can be assigned directly within SQL models using the `config()` function:

```sql
{{ config(
    tags=["finance", "daily_refresh"]
) }}

SELECT *
FROM {{ ref('stg_transactions') }}
```

This assigns both the "finance" and "daily\_refresh" tags to this specific model.

#### 2. Defining Tags in `dbt_project.yml`

Tags can also be applied at the project level, affecting entire folders or groups of models:

```yaml
models:
  my_project:
    +tags: "core"  # Assigns a single tag

    staging:
      +tags: ["staging", "raw_data"]  # Multiple tags

    marts:
      +tags:
        - "mart"
        - "business_logic"
```

***

### Tag Inheritance

Models inside a folder inherit the parent folder's tags unless overridden. This creates a hierarchical tagging system that is easy to maintain.

Example:

```
models/
  staging/
    customers.sql   → Tags: ["staging", "raw_data"]
    orders.sql      → Tags: ["staging", "raw_data"]
  marts/
    dim_customer.sql → Tags: ["mart", "business_logic"]
```

Individual models can add to inherited tags:

```sql
-- models/staging/special_orders.sql
{{ config(
    tags=["critical"]  # Adds to inherited ["staging", "raw_data"]
) }}

SELECT * FROM {{ ref('stg_orders') }}
```

This model would have tags: \["staging", "raw\_data", "critical"]

***

### Applying Tags to Different Resource Types

Tags can be applied to various dbt resource types:

#### Snapshots

```yaml
snapshots:
  my_project:
    +tags: ["historical_data"]
```

#### Seeds

```yaml
seeds:
  my_project:
    +tags: ["seed_data"]
```

#### Sources

```yaml
sources:
  - name: external_source
    tags: ['external']
```

***

### Using Tags for Selection

Once tags are defined, you can use them with dbt commands to select specific resources.

#### Selection Examples

| Command                                                       | Description                                                             |
| ------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `dbt run --select tag:daily_refresh`                          | Run only models with the `daily_refresh` tag                            |
| `dbt run --select tag:daily_refresh tag:critical`             | Run models with either `daily_refresh` OR `critical` tags               |
| `dbt run --select tag:daily_refresh --exclude tag:deprecated` | Run models with `daily_refresh` but exclude those with `deprecated` tag |
| `dbt run --select staging,tag:finance`                        | Run all models tagged `finance` in the `staging` folder                 |
| `dbt run --select tag:critical+`                              | Run `critical` models and their downstream dependencies                 |

#### Tag Selection Patterns

| Selection Pattern     | What It Selects                              | Example                                     |
| --------------------- | -------------------------------------------- | ------------------------------------------- |
| `tag:name`            | All resources with this tag                  | `dbt run --select tag:nightly`              |
| `tag:name1 tag:name2` | Resources with either tag                    | `dbt run --select tag:nightly tag:critical` |
| `tag:name+`           | Tagged resources and downstream dependencies | `dbt run --select tag:base+`                |
| `+tag:name`           | Tagged resources and upstream dependencies   | `dbt run --select +tag:reporting`           |
| `--exclude tag:name`  | Everything except resources with this tag    | `dbt run --exclude tag:deprecated`          |

***

### Best Practices for Using Tags

#### Use Consistent Naming Conventions

Standardized naming improves clarity and prevents confusion.

```yaml
# Good
+tags: ["daily_refresh", "finance_data"]

# Avoid inconsistent casing or spacing
+tags: ["Daily", "Finance", "financial-data"]
```

#### Document Your Tagging Strategy

Clearly define tag meanings in your project's documentation.

```markdown
# Tag Definitions
- `daily_refresh`: Models refreshed daily.
- `finance_data`: Contains financial-related tables.
- `pii`: Includes personally identifiable information.
```

#### Use Granular Tags

Avoid broad, generic tags. Instead, use precise labels for better control.

```yaml
# Good
+tags: ["customer_metrics", "daily_refresh"]

# Too broad
+tags: ["metrics", "regular"]
```

#### Tag Models by Layer

Use tags to represent data modeling layers in your project.

```yaml
models:
  staging:
    +tags: ["bronze_layer"]
  intermediate:
    +tags: ["silver_layer"]
  marts:
    +tags: ["gold_layer"]
```

***

### Common Use Cases for Tags

#### Refresh Scheduling

Define tags based on refresh frequency for better execution control:

```yaml
models:
  my_project:
    hourly:
      +tags: ["hourly_refresh"]
    daily:
      +tags: ["daily_refresh"]
```

Then in your orchestration tool, schedule different runs:

```bash
# Morning run for daily models
dbt run --select tag:daily_refresh

# Every hour for hourly models
dbt run --select tag:hourly_refresh
```

#### Data Classification

Differentiate datasets based on sensitivity or access level:

```yaml
models:
  my_project:
    +tags: ["contains_pii"]
    public:
      +tags: ["public_data"]
```

This helps implement appropriate security controls and auditing.

#### Testing Strategy

Prioritize critical models in testing workflows:

```yaml
models:
  my_project:
    critical:
      +tags: ["critical_path", "requires_alert"]
```

Run critical tests more frequently:

```bash
dbt test --select tag:critical_path
```

***

### Troubleshooting Tag Issues

If dbt isn't selecting resources correctly based on tags, consider these troubleshooting steps:

#### Tag Inheritance Issues

Verify parent folder configurations in `dbt_project.yml`:

```bash
# List all models with their tags
dbt ls -m "my_project.staging.*" --output path
```

#### Selection Syntax Errors

Ensure tag names match exactly (case-sensitive):

```bash
# Try with exact case
dbt run --select tag:daily_refresh  # Not tag:Daily_Refresh
```

#### Using dbt ls to Validate Tags

Use the `dbt ls` command to check which models have specific tags:

```bash
# List all models with the "finance" tag
dbt ls --select tag:finance
```

By effectively implementing a tagging strategy, you can organize your dbt project more efficiently, streamline your workflows, and gain better control over how your transformations are executed.
