Skip to main content

Dependency Graph

For Data Analysts

Olytix Core automatically builds a Directed Acyclic Graph (DAG) of dependencies between all project components. This graph determines execution order and enables impact analysis.

What is the Dependency Graph?

The dependency graph tracks relationships between all artifacts:

Dependency Graph

Click nodes to explore dependencies. Animated edges show data flow direction.

React Flow mini map
Legend
🗄️Source
⚙️Model
🧊Cube
🎯Metric

Graph Structure

Nodes

Every artifact is a node:

Node TypeExampleCreated From
Source Tablesource.raw.orderssources/*.yml
Modelmodel.fct_ordersmodels/**/*.sql
Cubecube.orderscubes/*.yml
Metricmetric.monthly_revenuemetrics/*.yml

Edges

Edges represent dependencies:

Edge TypeFromToCreated By
Source ReferenceModelSource{{ source('name', 'table') }}
Model ReferenceModelModel{{ ref('model_name') }}
Cube BaseCubeModelsql: "SELECT * FROM {{ ref('model') }}"
Cube JoinCubeCubejoins: [{cube: other_cube}]
Metric BaseMetricCube Measureexpression: cube.measure

How Dependencies Are Detected

Source Dependencies

Using source() in SQL:

-- models/stg_orders.sql
SELECT * FROM {{ source('raw', 'orders') }}

Creates edge: model.stg_orderssource.raw.orders

Model Dependencies

Using ref() in SQL:

-- models/fct_orders.sql
SELECT
o.*,
c.customer_name
FROM {{ ref('stg_orders') }} o
LEFT JOIN {{ ref('stg_customers') }} c ON o.customer_id = c.customer_id

Creates edges:

  • model.fct_ordersmodel.stg_orders
  • model.fct_ordersmodel.stg_customers

Cube Dependencies

Using ref() in cube SQL:

cubes:
- name: orders
sql: "SELECT * FROM {{ ref('fct_orders') }}"

Creates edge: cube.ordersmodel.fct_orders

Metric Dependencies

Referencing cube measures:

metrics:
- name: monthly_revenue
expression: orders.total_revenue

Creates edge: metric.monthly_revenuecube.orders.total_revenue

Viewing the Graph

CLI Commands

# View full graph
olytix-core graph

# View graph for specific node
olytix-core graph --select orders

# View upstream dependencies
olytix-core graph --select +fct_orders # Everything fct_orders depends on

# View downstream dependents
olytix-core graph --select fct_orders+ # Everything that depends on fct_orders

# Export as DOT format
olytix-core graph --format dot > graph.dot

API Endpoints

# Get full graph
curl http://localhost:8000/api/v1/graph

# Get graph for specific node
curl http://localhost:8000/api/v1/graph/model/fct_orders

Visualization

Graph: +fct_orders (upstream dependencies)
═══════════════════════════════════════════════════════════════

source.raw.orders ────────────────┐

source.raw.customers ────────────┐│
││
source.raw.products ────────────┐││
│││
▼▼▼
model.stg_orders

model.stg_customers ────┤

model.stg_products ─────┤


model.fct_orders

═══════════════════════════════════════════════════════════════

Execution Order

Topological Sort

Olytix Core uses topological sorting to determine execution order:

Execution Order for: olytix-core run
═══════════════════════════════════════════════════════════════

Level 0 (Sources - already exist):
✓ source.raw.orders
✓ source.raw.customers
✓ source.raw.products

Level 1 (No dependencies on other models):
→ model.stg_orders
→ model.stg_customers
→ model.stg_products

Level 2 (Depends on Level 1):
→ model.int_order_items

Level 3 (Depends on Level 2):
→ model.fct_orders

Level 4 (Depends on Level 3):
→ model.fct_order_summary

═══════════════════════════════════════════════════════════════

Parallel Execution

Models at the same level can run in parallel:

Level 1: ├── stg_orders     ──┐
├── stg_customers ──┼── (parallel)
└── stg_products ──┘

Level 2: └── fct_orders ── (waits for Level 1)

Selection Syntax

Select by Name

# Exact match
olytix-core run --select fct_orders

# Multiple models
olytix-core run --select fct_orders fct_customers

# Using comma
olytix-core run --select fct_orders,fct_customers

Select with Operators

# Plus prefix: select model and all upstream
olytix-core run --select +fct_orders

# Plus suffix: select model and all downstream
olytix-core run --select fct_orders+

# Both: full lineage
olytix-core run --select +fct_orders+

# N levels: limit depth
olytix-core run --select 1+fct_orders # Just immediate parents
olytix-core run --select fct_orders+1 # Just immediate children

Select by Path

# All models in folder
olytix-core run --select models/marts/*

# All staging models
olytix-core run --select models/staging/*

Select by Tag

# Models with tag
olytix-core run --select tag:daily

# Exclude tagged models
olytix-core run --exclude tag:deprecated

Select by Type

# All sources
olytix-core list --type source

# All cubes
olytix-core list --type cube

Cycle Detection

Olytix Core prevents circular dependencies:

ERROR: Circular dependency detected!

Path: model.a → model.b → model.c → model.a

Fix: Remove one of these references to break the cycle.

Common Causes

  1. Mutual references

    -- model_a.sql
    SELECT * FROM {{ ref('model_b') }}

    -- model_b.sql
    SELECT * FROM {{ ref('model_a') }} -- Creates cycle!
  2. Indirect cycles

    A → B → C → A  -- Three-node cycle

Solutions

  • Restructure to remove cycle
  • Extract shared logic to a third model
  • Use staging models as common base

Impact Analysis

Use the graph for impact analysis:

Upstream Impact

"What does this model depend on?"

olytix-core impact --upstream fct_orders
Upstream Dependencies: fct_orders
═══════════════════════════════════════════════════════════════

Sources (3):
• source.raw.orders
• source.raw.customers
• source.raw.products

Models (4):
• stg_orders
• stg_customers
• stg_products
• int_order_items

If these change, fct_orders may be affected.
═══════════════════════════════════════════════════════════════

Downstream Impact

"What will break if I change this?"

olytix-core impact --downstream stg_orders
Downstream Dependents: stg_orders
═══════════════════════════════════════════════════════════════

Models (3):
• int_order_items
• fct_orders
• fct_order_summary

Cubes (1):
• orders

Metrics (5):
• monthly_revenue
• order_count
• average_order_value
• revenue_growth
• customer_orders

Changes to stg_orders will affect these 9 artifacts.
═══════════════════════════════════════════════════════════════

Graph Best Practices

1. Keep It Shallow

Prefer wider, shallower graphs:

Good:                          Bad:
A ──┬── C A ── B ── C ── D ── E ── F
│ (Deep chain = slower builds)
B ──┴── D

2. Minimize Cross-Dependencies

Good:                          Bad:
Source1 → Staging1 → Mart1 Source1 ──┐
├── Staging ──┐
Source2 → Staging2 → Mart2 │ ├── Mart
Source2 ──┘ │
Staging2 ────┘

3. Use Clear Layers

sources/     →  models/staging/  →  models/marts/  →  cubes/  →  metrics/
(raw data) (1:1 cleaning) (joins/calcs) (semantic) (KPIs)

4. Tag for Selection

# In model
{{ config(tags=['daily', 'finance']) }}

# Select by tag
olytix-core run --select tag:daily

Next Steps

Now that you understand the dependency graph:

  1. Learn about compilation →
  2. Understand lineage →
  3. Start building models →