System Design · hard

Design an incremental dbt model for a table where events can arrive late. What do you use as the incremental filter?

Asked in Analytics Engineer interviews, in the System Design round.

Short answer

Filter on event time with a lookback window — in is_incremental(), where event_time >= (select max(event_time) from this model) minus a few days — and set a unique_key so late rows update instead of duplicating. Use merge or delete+insert on the partition, not append. State the tradeoff: a wider lookback is more correct but reprocesses more each run.

How to answer it

Filter on event time with a lookback window, not on the maximum timestamp alone, and give the model a unique key so late rows update rather than duplicate.

{{ config(
    materialized='incremental',
    unique_key='event_id',
    incremental_strategy='merge'
) }}

select event_id, user_id, event_time, event_type, amount
from {{ source('app', 'events') }}
{% if is_incremental() %}
  where event_time >= (
    select coalesce(max(event_time), '1900-01-01') from {{ this }}
  ) - interval '3 days'
{% endif %}

Why each piece:

Test it: a uniqueness test on event_id, and a check that a full refresh and the incremental result agree on a sample window.

Related questions

Practice this for real