Optimizing Performance with Ephemeral Models
In this lesson, you will learn how to use ephemeral materializations to inject modular SQL logic into your downstream models without cluttering your database with unnecessary intermediate tables.
Why Avoid Physical Tables?
When building dbt pipelines, we often create "helper" models to clean or join data before feeding it into a final analysis. If you materialize these as standard table or view types, dbt creates a physical object in your data warehouse for every single step. This can bloat your database, increase storage costs, and create maintenance headaches for objects that are only ever used as inputs for another transformation.
The Ephemeral Solution
The ephemeral materialization is a dbt-specific strategy that tells the compiler: "Do not create a table or view for this model." Instead, when you reference this model in another file using the {{ ref() }} function, dbt will take the SQL code from the ephemeral model and wrap it in a Common Table Expression (CTE) inside the final query.
Consider a model named int_orders_cleaned.sql:
{{ config(materialized='ephemeral') }}
SELECT
order_id,
customer_id,
LOWER(status) as status
FROM {{ ref('stg_orders') }}
WHERE status != 'cancelled'
When you reference this in a downstream model like fct_sales.sql:
SELECT * FROM {{ ref('int_orders_cleaned') }}
During execution, dbt compiles your final SQL to look like this:
WITH int_orders_cleaned AS (
SELECT order_id, customer_id, LOWER(status) as status
FROM your_schema.stg_orders
WHERE status != 'cancelled'
)
SELECT * FROM int_orders_cleaned
Performance Benefits
By using ephemeral models, you keep your database clean. Because the code is injected directly into the downstream query as a CTE, your data warehouse's query optimizer can often see the entire logic tree at once, which can lead to better execution plans compared to querying a series of intermediate physical views. It is the perfect tool for modularizing code while keeping your warehouse schema lightweight.
Key Takeaway: Use the ephemeral materialization to organize your logic into reusable SQL snippets that disappear at runtime, reducing database clutter while maintaining a clean, modular pipeline.