Staging, intermediate, and marts pattern in dbt - Time & Space Complexity
When using the staging, intermediate, and marts pattern in dbt, we want to understand how the time to build models grows as data size increases.
We ask: How does the processing time change when data gets bigger in each layer?
Analyze the time complexity of this dbt model sequence.
-- staging/customers.sql
select * from raw.customers
-- intermediate/orders_clean.sql
select * from raw.orders where status = 'complete'
-- marts/sales_summary.sql
select customer_id, count(*) as total_orders
from intermediate.orders_clean
group by customer_id
This code shows three layers: staging copies raw data, intermediate filters orders, and marts aggregate sales per customer.
Look at the main repeated work in each layer.
- Primary operation: Scanning rows in tables (select * or filtering)
- How many times: Once per layer, each processes all input rows
As input rows increase, each layer processes more data.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 rows scanned per layer |
| 100 | About 100 rows scanned per layer |
| 1000 | About 1000 rows scanned per layer |
Pattern observation: The work grows roughly in direct proportion to the number of rows.
Time Complexity: O(n)
This means the time to build these models grows linearly as the data size grows.
[X] Wrong: "Adding more layers multiplies the time complexity exponentially."
[OK] Correct: Each layer processes data once, so total time adds up linearly, not multiplies exponentially.
Understanding how data flows through layers and affects processing time helps you design efficient data pipelines and explain your approach clearly.
"What if the marts layer added a nested loop join on a large table? How would the time complexity change?"
Practice
Staging, intermediate, and marts?Solution
Step 1: Understand the role of staging
The staging layer is where raw data is cleaned and standardized to make it ready for analysis.Step 2: Differentiate from other layers
Intermediate and marts layers perform transformations and aggregations, while staging focuses on cleaning.Final Answer:
To clean and prepare raw data for further transformations -> Option CQuick Check:
Staging = cleaning raw data [OK]
- Confusing staging with marts layer
- Thinking staging creates final reports
- Assuming staging stores backups
Solution
Step 1: Recall dbt model referencing syntax
dbt uses the Jinja functionref()inside double curly braces to reference models.Step 2: Identify correct syntax
The correct syntax is{{ ref('model_name') }}, so{{ ref('stg_customers') }}is correct.Final Answer:
SELECT * FROM {{ ref('stg_customers') }} -> Option BQuick Check:
Use {{ ref('model') }} to reference models [OK]
- Omitting curly braces around ref()
- Using source() instead of ref() for models
- Calling ref() without curly braces
SELECT
customer_id,
COUNT(order_id) AS total_orders
FROM {{ ref('stg_orders') }}
GROUP BY customer_idWhat will be the output columns of this model?
Solution
Step 1: Analyze SELECT statement
The query selectscustomer_idand countsorder_idastotal_orders.Step 2: Understand GROUP BY effect
Grouping bycustomer_idmeans output will have one row per customer with total orders counted.Final Answer:
customer_id, total_orders -> Option AQuick Check:
Output columns = customer_id and total_orders [OK]
- Expecting order_id as output column
- Missing aggregated column in output
- Confusing GROUP BY with WHERE clause
SELECT
customer_id,
SUM(total_orders) AS total_orders
FROM {{ ref('int_customer_orders') }}
GROUP BY customer_idBut the model fails with an error about
total_orders. What is the likely cause?Solution
Step 1: Check referenced model columns
The error suggeststotal_orderscolumn is missing inint_customer_orders.Step 2: Validate aggregation usage
SUM() is valid in marts layer and GROUP BY is present, so those are not issues.Final Answer:
The referenced modelint_customer_ordersdoes not have a column namedtotal_orders-> Option DQuick Check:
Column missing in referenced model causes error [OK]
- Assuming SUM() is invalid in marts
- Forgetting GROUP BY with aggregation
- Misusing ref() syntax
Solution
Step 1: Follow pattern responsibilities
Staging cleans raw data, intermediate transforms data per store, marts create final aggregates like sales per region.Step 2: Use intermediate model in marts
Use the intermediate sales per store model as input to marts, then aggregate by region for the report.Final Answer:
Reference the intermediate sales per store model in the marts layer and aggregate sales by region -> Option AQuick Check:
Marts aggregate intermediate data for final reports [OK]
- Skipping intermediate layer aggregation
- Aggregating raw data directly in marts
- Doing final aggregation in staging
Ready to prove it?
Pass the test and this pattern moves unknown
