In this lesson, you will learn how to configure dbt models to process only new or updated records, significantly reducing warehouse costs and execution time.
When dealing with massive datasets—such as multi-year event logs—reprocessing the entire table every time your pipeline runs becomes prohibitively expensive and slow. An incremental model solves this by only transforming the "delta"—the new data that has arrived since the last time the model was run.
How It Works
Instead of a standard table or view materialization, you define your model as incremental. You then use a special is_incremental() macro to tell dbt which rows to include during a "refresh" run versus a "full load" run.
Consider a model that tracks daily user activity:
{{
config(
materialized='incremental',
unique_key='event_id'
)
}}
select *
from {{ source('raw_events', 'events') }}
{% if is_incremental() %}
-- Only process records that arrived since the last run
where event_timestamp >= (select max(event_timestamp) from {{ this }})
{% endif %}
Key Considerations
- The
is_incremental()macro: This returnstrueonly if the target table already exists and you are not performing a full-refresh run. If it is false, dbt will simply recreate the entire table. - The
unique_key: This is crucial. By specifying aunique_key, dbt knows how to "merge" the new records into your existing table. If an incoming record shares an ID with an existing row, dbt will update the existing row rather than duplicating it. This ensures your data remains accurate even if records are updated. - Efficiency: Because your
whereclause filters the source data down to only what is new, your warehouse processes a fraction of the total rows, leading to faster completion and lower compute costs.
By moving from full-table refreshes to incremental updates, you transform your data pipeline from a resource-heavy burden into a lean, efficient process that scales alongside your data.
Key Takeaway: Incremental models allow you to process only the newest data by filtering your source query and using a unique_key to merge updates, drastically optimizing performance for large-scale datasets.