Skip to content

DAG & Dependencies

Rocky builds a directed acyclic graph (DAG) from model dependencies to determine execution order. Models declare their upstream dependencies explicitly, and Rocky uses topological sorting to produce a valid execution plan with parallel execution layers.

Each model declares what it depends on using the depends_on field in its TOML configuration:

name = "fct_orders"
depends_on = ["stg_orders", "dim_customers"]

This means fct_orders cannot run until both stg_orders and dim_customers have completed.

Rocky uses Kahn’s algorithm to produce a topological ordering of models. The output is deterministic: when multiple models have no remaining dependencies (i.e., they are tied), they are sorted alphabetically.

Models are grouped into layers. All models in a layer can run in parallel because their dependencies have been satisfied by earlier layers.

Example dependency graph:

stg_customers ──→ dim_customers ──┐
├──→ fct_orders
stg_orders ───────────────────────┘

This produces three execution layers:

Layer 0: stg_customers, stg_orders (no dependencies, run in parallel)
Layer 1: dim_customers (depends on stg_customers)
Layer 2: fct_orders (depends on stg_orders + dim_customers)

Rocky executes all models in Layer 0 concurrently, waits for them to finish, then executes Layer 1, and so on.

Rocky validates the DAG at rocky validate time, catching problems before any SQL is executed.

Circular dependencies are detected and reported with the full cycle path:

model_a.toml
name = "model_a"
depends_on = ["model_b"]
# model_b.toml
name = "model_b"
depends_on = ["model_a"]
Error: Circular dependency detected: model_a → model_b → model_a

References to models that don’t exist are caught:

name = "fct_orders"
depends_on = ["stg_orders", "nonexistent_model"]
Error: Unknown dependency "nonexistent_model" in model "fct_orders"

Not every table reference creates a dependency. Rocky classifies references based on how they are qualified in the SQL:

SQL referenceClassificationDAG behavior
stg_orders (matches a Rocky model)Model dependencyExecution edge in DAG
stg_orders (no matching model)External referenceIgnored by DAG
dbt_fivetran.stg_facebook_ads__ad_historyTwo-part externalIgnored by DAG
analytics.dbt_fivetran.stg_facebook_ads__ad_historyThree-part externalIgnored by DAG

Bare names are resolved against the project’s models. If a match is found, a dependency edge is created. If no model matches, the reference is treated as external.

Two-part (schema.table) and three-part (catalog.schema.table) references are always treated as external sources. Rocky reads from them but does not manage, build, or schedule them.

This distinction enables hybrid workflows where Rocky models consume tables produced by other tools (dbt packages, Fivetran connectors, manual ETL) without needing to convert or import them. External tables appear in column-level lineage but are excluded from execution planning.

-- stg_orders is a Rocky model -> DAG dependency
-- dbt_fivetran.stg_facebook_ads__ad_history is external -> no dependency
SELECT
o.order_id,
f.ad_name
FROM stg_orders o
JOIN dbt_fivetran.stg_facebook_ads__ad_history f
ON o.campaign_id = f.campaign_id

See Using Rocky with dbt Packages for a full guide on this pattern.

dbt uses Jinja’s {{ ref('model_name') }} macro inside SQL to create implicit dependencies. The dependency graph is extracted by parsing Jinja templates:

-- dbt model
SELECT *
FROM {{ ref('stg_orders') }}
JOIN {{ ref('dim_customers') }} USING (customer_id)

Rocky uses explicit depends_on declarations in TOML:

depends_on = ["stg_orders", "dim_customers"]

The differences:

dbtRocky
DeclarationImplicit via {{ ref() }} in SQLExplicit depends_on in TOML
When validatedDuring parsing/compilationAt rocky validate time
SQL puritySQL mixed with JinjaPure SQL, no template language
Editor supportRequires dbt LSP for ref()Standard SQL tooling works

Rocky’s approach means the DAG is validated early and independently of SQL parsing. You can run rocky validate to check the entire dependency graph without connecting to any warehouse.