Where we are in the pipeline
In b2 you connected to Daybreak's sources and landed a copy of each. But a real pipeline runs every day, not once - and re-copying the entire source every single day is slow and expensive. This session is about the smart part of ingestion: pulling only what changed since last time, reliably, without double-loading. Still the same lifecycle seam - generation into ingestion - now done efficiently.
Ingestion on a continuum 6 min live
Ingestion is not one choice, it is a slider. At one end, full reload: copy the entire source every run - dead simple, always correct, but expensive and slow as data grows. At the other, incremental: pull only rows that are new or changed - cheap and fast, but you have to track what you have already seen. Most pipelines sit somewhere on this line, chosen table by table.
LiveETL vs ELT - where the transform runs3 min▶
The other big ingestion decision is when you transform. The letters are the order of operations:
- ETL (extract, transform, load): reshape the data before it lands in the destination. The old default, from when storage was expensive and you cleaned data to save space.
- ELT (extract, load, transform): land the raw data first, transform it later, inside the destination. The modern default - cloud storage is cheap, so you keep the raw copy and reshape on demand.
This whole track is ELT-shaped: b2-b4 land raw data, b5 and b8 transform it after it lands. Keeping the raw copy means you can re-transform any time without re-extracting from the source.
Why modern stacks went ELT. When a warehouse charged by the gigabyte, teams transformed first to store less (ETL). Once cloud storage dropped to cents, the calculus flipped: land everything raw, transform later, and you get replay, auditability, and the freedom to fix a transform bug without touching the source. That flip is why "load then transform" is now the default.
Self-studyThe cost of full reload as data grows2 min read▶
Full reload feels harmless when a table has a thousand rows. The problem is that its cost grows with the total size of the source, not the amount of new data. A table that gains 1% new rows a day still gets copied 100% every night under full reload. After a year that is 365 full copies of an ever-larger table to capture a trickle of change. Incremental flips the cost to scale with change, not history - which is why every high-volume fact table eventually moves to it.
The watermark pattern 6 min live
Incremental ingestion needs one piece of memory: the high-water mark - the largest timestamp or id you pulled last run. Next run, you pull only rows past it. That is the whole trick. The watermark is a single saved value, and the extract is just WHERE column > watermark.
LiveSimulate an incremental pull3 min▶
Pretend your last run stopped at a watermark date. This run pulls only orders after it. Change the date and re-run to see the "new rows" count move. Press ▶ Run (first run caches the ~8 MB engine).
-- watermark = the max order_date we saw last run SELECT count(*) AS new_rows_since_watermark FROM orders WHERE order_date > '2026-04-01';
Self-studyLate-arriving data & the safety window3 min read▶
A naive watermark assumes rows always arrive in order. Reality disagrees. A mobile app buffers events offline and syncs a two-day-old order tomorrow; a batch job backfills yesterday's records at noon. If your watermark jumps straight to "now", those late rows arrive behind the mark and never get pulled - silent data loss.
Batch windows and idempotency 5 min live
Incremental runs on a schedule, in windows - one file per day, per hour, or per month. The rule that keeps windows safe is idempotency: re-running the same window must not double-load. The clean pattern is one file per window, named by its window, so a re-run overwrites rather than appends.
LiveOne dated file per window3 min▶
Extract one month of orders to a file named for that window. Re-running writes the same file, so the window is idempotent - run it once or ten times, the landed result is identical.
-- the March 2026 window, landed as its own dated file
COPY (SELECT * FROM orders
WHERE order_date >= '2026-03-01'
AND order_date < '2026-04-01')
TO 'windows/orders_2026-03.parquet' (FORMAT PARQUET);
SELECT count(*) AS rows_in_march_window
FROM 'windows/orders_2026-03.parquet';
Incremental extract, live ★ 6 min · everyone builds
Watch full versus incremental side by side. First count the whole source, then land only the rows past a watermark, then count the incremental file. The gap between the two counts is exactly the bytes you did not move - the whole point of incremental ingestion.
Full size: count every row in the source - what a full reload would copy.
Incremental extract: land only orders after the watermark to a Parquet file.
Compare: one result shows full count next to incremental count. The difference is the saving.
-- extract only rows past the watermark COPY (SELECT * FROM orders WHERE order_date > '2026-04-01') TO 'inc/orders_new.parquet' (FORMAT PARQUET); -- full reload size vs incremental size, side by side SELECT (SELECT count(*) FROM orders) AS full_reload_rows, (SELECT count(*) FROM 'inc/orders_new.parquet') AS incremental_rows;
This gap is money at scale. On a fact table with a billion rows gaining a million a day, full reload moves a billion rows every night; incremental moves a million. Same freshness, one-thousandth of the transfer, compute, and cloud bill. The two-line difference you just ran is the single highest-leverage decision in most ingestion pipelines.
Your turn: tune the ingestion ★ 8 min · build your own
Each editor starts fresh from Daybreak's raw source. Change the watermark, size a batch window, then reason about the trade-off. All three run against the source tables.
LiveQ1 · Write the incremental filter for a new watermark3 min▶
Pick a different watermark date and count only the orders after it. Try a few dates and watch the "new rows" number respond.
SELECT count(*) AS new_since_watermark FROM orders WHERE order_date > '2026-05-01';
LiveQ2 · Daily vs monthly batch window4 min▶
How many orders would a single daily window carry, versus a full month? One query shows both, so you can feel the window-size trade-off.
SELECT
count(*) FILTER (WHERE order_date = '2026-03-15') AS one_day,
count(*) FILTER (WHERE order_date >= '2026-03-01'
AND order_date < '2026-04-01') AS one_month
FROM orders;
Self-studyQ3 · Full reload or incremental?3 min▶
A thought exercise, no SQL. Given a table, how do you decide? The rule of thumb:
- Small dimension table (customers, products): full reload. A few hundred or thousand rows are cheap to re-copy, and you dodge all the watermark bookkeeping. Simpler is better when the table is small.
- Huge, append-heavy fact table (orders, events, clicks): incremental. The table only grows, so full reload's cost climbs forever while incremental stays flat at "today's new rows".
- The tie-breaker: if the source has a reliable, indexed timestamp or id to watermark on, incremental is easy. If it does not, full reload may be the only correct option until the source adds one.
Try it yourself - this week ◐ 20-30 min total
- For each table you ingest at work, decide full reload or incremental and write down the one-line reason. Note which lack a watermark column.
- Take Demo 1 and add a third figure: the percentage the incremental extract saved versus full reload.
- Pick one incremental source and design its safety window - how many days back would you set the watermark, and why?
- Label one real pipeline at work as ETL or ELT. If it is ETL, ask what you would gain by keeping the raw landed copy.
- Bring one source where late-arriving data has burned you to session b4 - formats and storage are next.
Official sources covered
This session teaches the working core of the DeepLearning.AI Data Engineering Professional Certificate (Joe Reis) and Reis & Housley's Fundamentals of Data Engineering, run on a live engine instead of slides. This page covers:
Three questions before you go 🎯 ◐ 90 seconds
1 · What is the difference between full reload and incremental ingestion?
Full reload re-copies everything each run - simple but costly as data grows. Incremental pulls only what changed since last run, so its cost scales with change, not history.
2 · What does a watermark do in incremental ingestion?
The watermark is a single saved high-water value. The next extract is just WHERE column > watermark - that one memory turns a full scan into "only new rows".
3 · Why do modern data stacks default to ELT over ETL?
When storage got cheap, the calculus flipped: land raw (load), transform later. You keep the raw copy for replay, auditing, and fixing transforms without touching the source.