Start here
What you will learn
- Full load and incremental load: two ways to copy data.
- Two ways to find new rows: by created date, or by updated_at.
- The half-open window, so no row is read twice or missed.
- Late rows, and a small lookback that catches them.
- A backfill: run the same job for a day in the past.
- A safe backfill plan, and one trap with dimension values.
A pipeline copies data from a source table to a warehouse table. The source is where the app writes. The warehouse table is the copy that analysts read.
One execution of the job is a run. This chapter uses two tables: orders in the source, and dw_orders in the warehouse. In the story, today is 2026-01-22.
The source table has a new column, updated_at. It holds the date the row last changed. The app sets it on every insert and every update.
| order_id | order_date | amount | updated_at |
|---|---|---|---|
| 101 | 2026-01-03 | 40.00 | 2026-01-03 |
| 102 | 2026-01-10 | 25.00 | 2026-01-10 |
| 103 | 2026-01-11 | 60.00 | 2026-01-11 |
| 104 | 2026-01-15 | 15.50 | 2026-01-15 |
| 105 | 2026-01-20 | NULL | 2026-01-20 |
| 106 | 2026-01-21 | 80.00 | 2026-01-21 |
SELECT COUNT(*) AS rows_in_source,
MAX(updated_at) AS newest_change
FROM orders;| rows_in_source | newest_change |
|---|---|
| 6 | 2026-01-21 |
Later we change one row on purpose. On 2026-01-25, order 105 is paid. Its amount changes from NULL to 22.00, and its updated_at becomes 2026-01-25.
Remember order 105. It breaks the first idea we try.
