Dependency Graph
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.
Graph Structure
Nodes
Every artifact is a node:
| Node Type | Example | Created From |
|---|---|---|
| Source Table | source.raw.orders | sources/*.yml |
| Model | model.fct_orders | models/**/*.sql |
| Cube | cube.orders | cubes/*.yml |
| Metric | metric.monthly_revenue | metrics/*.yml |
Edges
Edges represent dependencies:
| Edge Type | From | To | Created By |
|---|---|---|---|
| Source Reference | Model | Source | {{ source('name', 'table') }} |
| Model Reference | Model | Model | {{ ref('model_name') }} |
| Cube Base | Cube | Model | sql: "SELECT * FROM {{ ref('model') }}" |
| Cube Join | Cube | Cube | joins: [{cube: other_cube}] |
| Metric Base | Metric | Cube Measure | expression: 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_orders → source.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_orders→model.stg_ordersmodel.fct_orders→model.stg_customers
Cube Dependencies
Using ref() in cube SQL:
cubes:
- name: orders
sql: "SELECT * FROM {{ ref('fct_orders') }}"
Creates edge: cube.orders → model.fct_orders
Metric Dependencies
Referencing cube measures:
metrics:
- name: monthly_revenue
expression: orders.total_revenue
Creates edge: metric.monthly_revenue → cube.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
-
Mutual references
-- model_a.sql
SELECT * FROM {{ ref('model_b') }}
-- model_b.sql
SELECT * FROM {{ ref('model_a') }} -- Creates cycle! -
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: