How to Use dbt Sources

Last updated July 25, 2026 · By the SaturnSQL team

Declare raw tables in a YAML sources block, then reference them with the source() function. Sources make raw dependencies explicit in the DAG, can carry tests, and support freshness checks via dbt source freshness.

The database and schema keys point at where the raw data actually lives, while name is the alias you use in source(). loaded_at_field tells dbt which column holds the load timestamp so it can measure staleness, and the freshness thresholds decide when that becomes a warning rather than an error.

# models/staging/sources.yml
sources:
  - name: shop
    database: raw
    schema: shop_data
    tables:
      - name: raw_orders
        loaded_at_field: _loaded_at
        freshness:
          warn_after: {count: 12, period: hour}
          error_after: {count: 24, period: hour}

In a model

source() compiles to the fully qualified table name and registers the dependency, so the raw table appears in the DAG and in the docs lineage graph. The convention is to reference each source exactly once, in a staging model, and have everything downstream use ref() against that staging model instead.

SELECT * FROM {{ source('shop', 'raw_orders') }}

Checking freshness

dbt source freshness compares the maximum loaded_at_field value against your thresholds and writes results to target/sources.json. Run it before the main build in CI so a stale upstream load fails fast rather than quietly producing yesterday's numbers. Sources without loaded_at_field are skipped rather than reported.

dbt source freshness

Run this in SaturnSQL

SaturnSQL is a browser-based SQL editor for teams: shared query library, schema-aware autocomplete, and scheduled exports to Google Sheets and Slack.

Try it free

Related dbt guides