Skip to content
Books for Data Engineers
Published 2026-07-10Related book: dbt for Data Engineers

The DAG Is the Contract: dbt's Execution Model in One Picture

Ask a room of dbt users what dbt run does and most will say some version of "runs my SQL against the warehouse." That's true, but it skips the step that actually explains dbt's behavior in production: compile happens first, completely, before a single query touches your warehouse.

Compile vs. execute, not SQL vs. Python

When you run dbt build, dbt first resolves every ref() and source() call, renders every Jinja macro, and assembles the full dependency graph — the DAG — into a manifest.json. Only after that graph is fully resolved does execution begin, model by model, in topological order.

This is why a broken ref() to a model that doesn't exist fails at compile time, before any warehouse compute is spent — and why dbt run --select stg_claims+ can decide exactly which downstream models to touch without re-deriving anything at runtime. The DAG isn't a visualization dbt draws for you after the fact. It's the actual execution contract.

-- models/staging/storefront/stg_orders.sql
select
    order_id,
    customer_id,
    cast(order_date as date) as order_date,
    channel,
    order_status,
    order_amount,
    cast(updated_at as timestamp) as updated_at
from {{ source('storefront', 'orders') }}

That {{ source(...) }} call isn't a runtime lookup — it's resolved at compile time against sources.yml, which is exactly why a typo in a source name fails your dbt compile step, not a 2am production run three joins downstream.

Where this actually bites people

The engineers who get surprised by dbt in production are usually the ones who think about it query-by-query instead of graph-by-graph: wondering why a materialization change didn't take effect (compile cache), why a --full-refresh behaved differently across environments (adapter-specific incremental gaps), or why a Slim CI run rebuilt half the project for what looked like a one-line change (state:modified comparing more of the compiled node than they expected).

dbt for Data Engineers chapter 1 goes through the full execution model — compile vs. execute, the manifest, materializations and their adapter-specific gaps — free to read right now.