data_engineering / F7 · batch, streaming, and trust foundations · 8 / 8

Batch, streaming, and trust

The Part 0 capstone. Three fundamentals that decide whether a pipeline is correct, trustworthy, and affordable: when work runs (batch vs streaming), whether you can rely on the result (idempotency, determinism, reproducibility), and what it costs to run (throughput, unit cost, bottlenecks).

Where we are
This is the last lesson of Part 0 · Foundations, the capstone. Six lessons built the vocabulary — records, schemas, the relational model, OLTP/OLAP, the lakehouse and columnar layout, pipelines, and the shuffle that F6 ended on. This lesson ties three remaining fundamentals together, then hands you off to the post-training series proper. As always: an intuitive on-ramp first, then the mechanical version.

Theme 1 — Batch vs streaming: the time dichotomy

Every pipeline answers one question before any other: when does the work run? Either you collect input and process it in chunks on a schedule, or you process each event the instant it arrives. This single choice cascades into how you reason about correctness, ordering, and failure — so it is worth getting the picture right first.

Intuition — two ways to do laundry

Think about doing laundry. The normal way is batch: you wait until you have a full hamper, then wash it all in one load. It's efficient per item — one cycle of water, soap, and electricity cleans thirty shirts at once — but your favorite shirt isn't available until the whole load finishes. You trade freshness for efficiency, and you always know exactly what went in: a fixed pile of clothes.

Now imagine a magic machine that washes each sock the instant it gets dirty. That's streaming. Everything is always fresh — no waiting for a load to fill — but the machine never stops running, and keeping it correct is much harder. What if two socks arrive at once? What if a sock from yesterday's mud shows up late, after you already folded today's? The always-on machine has to answer questions the hamper never raised.

Mechanics — bounded jobs vs unbounded streams

Batch processes a bounded dataset to completion at intervals (hourly, nightly). Because the input is fixed and finite, batch optimizes for throughput and cost — it can sort, group, and shuffle the whole thing — and accepts latency as the price. It is easy to make reproducible: re-run the same job over the same fixed input and you get the same output.

Streaming processes an unbounded sequence of events with low latency, and that single difference introduces hard problems batch never faces:

The dichotomy is fundamental because correctness, ordering, and failure-recovery semantics differ completely between the two. A mental model built for one will quietly mislead you in the other.

  SAME EVENTS (1..7), TWO PROCESSING MODELS
  ───────────────────────────────────────────────────────────────────────

  BATCH — accumulate into a bin over an interval, process the whole bin at once
                  ┌──── bin 1 ────┐ ┌──── bin 2 ────┐ ┌──── bin 3 ────┐
  arrivals   ─────1──2────3───────┼─4─────5─────────┼─6──────7────────┼──▶ time
  results    ─────────────────────█─────────────────█─────────────────█──▶
                                  ▲                                    results appear in chunks
                                  └ whole bin 1 emitted here           (latency ≈ bin-fill time)

  STREAM — process each event the instant it arrives
  arrivals   ─────1──2────3─────────4─────5───────────6──────7──────────▶ time
  results    ─────▌──▌────▌─────────▌─────▌───────────▌──────▌──────────▶
                  └──┴────┴── one result per event, immediately ──┴──────┘
                                  (low latency, machine always on)

The trade is exactly latency vs throughput: batch waits a full bin before any result appears but amortizes fixed costs across the whole bin (cheap per record); streaming emits each result the instant its event lands (low latency) at the cost of being always-on and paying per-event overhead.

BatchStreaming
InputBounded — a fixed, finite datasetUnbounded — an endless sequence of events
Optimizes forThroughput & cost per recordLatency — freshness of each result
RunsOn a schedule, to completionContinuously, never finishes
Hard problemsMostly scale (the shuffle)Event-time, windows, watermarks, exactly-once
Reproducible?Naturally — input is fixedHard — input is a moving target
Intuition — backpressure

Picture a sink filling faster than it drains: the water rises and eventually overflows. The only fixes are to slow the tap or widen the drain. A streaming pipeline has the same physics. If a downstream stage consumes slower than an upstream stage produces, the queue between them grows without bound — and backpressure is the signal that flows back up to throttle the producer until it matches the consumer.

This is load-bearing later: it is exactly how the producer (rollout generation) and consumer (the trainer) stay rate-matched in lesson 10's RL online dataplane, where a mismatch either starves the GPUs or lets data go stale.

Theme 2 — The trust properties

Distributed pipelines (from F6) will fail mid-run and retry. A machine dies, a network blips, a job is restarted from a checkpoint. The question is not whether retries happen — they do — but whether a retry leaves your data correct or corrupts it. Three properties decide that, and they stack on top of each other.

Intuition — a button, a recipe, and a pantry

Idempotent — an elevator call button. Press it once or press it five times in frustration: the result is identical, one elevator arrives. The repeated presses don't stack up into five elevators. An operation is idempotent when doing it again changes nothing.

Deterministic — a recipe so precise that two different cooks, following it exactly, produce identical cakes. No "season to taste," no "bake until it looks done." Same instructions, same result, every time.

Reproducible — keeping not just the precise recipe but the exact batch of flour and the exact oven settings filed away, so you can bake that same cake next year and it comes out identical. Determinism plus a frozen record of everything that went in.

Mechanics — what each property means precisely

Here is the bug these properties prevent. A job appends its output, then crashes after writing but before recording success. The orchestrator retries the whole job — and the rows land again:

  NON-IDEMPOTENT  (append on rerun)        IDEMPOTENT  (overwrite by key)
  ─────────────────────────────────       ──────────────────────────────
  run 1:  append [A,B,C]  →  A B C         run 1:  upsert {A,B,C}  →  A B C
  crash + retry the job                    crash + retry the job
  run 2:  append [A,B,C]  →  A B C         run 2:  upsert {A,B,C}  →  A B C
                             A B C                                  (no change)
  ───────────────────────────────────     ──────────────────────────────
  result: 6 rows  ✗  silently doubled      result: 3 rows  ✓  retry was safe

The non-idempotent pipeline doesn't error — it succeeds, and quietly returns wrong numbers. That's the worst kind of failure, because nothing alerts you. Idempotency turns a retry from a corruption risk into a no-op.

PropertyPrecise statementBuys you
IdempotentN applications = 1 applicationSafe retries & re-runs
DeterministicSame input → same outputPredictable, testable behavior
ReproducibleDeterministic + versioned inputs/code/configRegenerate any past result exactly

Theme 3 — Cost & throughput thinking

The final fundamental is economic. A pipeline that is correct but costs ten times what it should, or runs ten times slower than it could, is a failed pipeline. Reasoning about cost and speed is its own skill — and the trap is optimizing the wrong thing.

Intuition — a road trip on a budget

Plan a road trip on a budget and you naturally think in rates and bottlenecks: miles per gallon, dollars per mile, hours per leg. And you ask the sharp question: which leg is the slow one? Is it traffic through the city? The time lost refueling? The mountain pass that drops you to 30 mph?

The crucial insight: a faster engine is pointless if you're stuck in traffic. Doubling your top speed saves nothing on the leg where you're bumper-to-bumper. To go faster you must find and fix the actual bottleneck — and optimizing anything else is wasted effort, money, and time.

Mechanics — rates, unit cost, and the bottleneck resource

Characterize a pipeline with two numbers:

Then find the bottleneck resource — the one thing the pipeline is waiting on — because optimizing anything else changes nothing:

That last point connects directly to F6. For narrow (embarrassingly parallel) work, adding workers W scales nearly linearly — more hands, more done. But for wide work that requires a shuffle, every worker may talk to every other worker, so coordination grows like O(W²). Past a point, another worker adds more shuffle overhead than useful work, and the job gets slower. A faster engine in traffic.

  WHERE IS THE TIME GOING?  (profile before you optimize)
  ────────────────────────────────────────────────────────
  stage        bar (share of wall-clock)          verdict
  read         ████████████████████████   62%     ◀ BOTTLENECK (I/O-bound)
  transform    ██████                      16%
  shuffle      ████████                    20%
  write        █                            2%
  ────────────────────────────────────────────────────────
  buying faster CPUs here speeds up the 16% transform → barely moves total.
  reading less data (column pruning, partition filter) attacks the 62% → wins.
The cardinal rule
Measure first, optimize the bottleneck, measure again. Intuition about where time goes is wrong often enough that profiling is not optional. A 2× speedup on a stage that's 5% of runtime is a rounding error; a 20% speedup on the stage that's 62% of runtime is the whole game.

How these three set up the post-training series

These three themes are fundamental, general data engineering — they apply to any pipeline, anywhere. But they also set up the post-training series you're about to read, directly:

Takeaway
Part 0 is done. You now have the working vocabulary of data engineering — records, schemas, the relational model, OLTP/OLAP, the lakehouse, columnar layout, pipelines, the shuffle, batch vs streaming, and the trust properties (idempotency, determinism, reproducibility) — plus the habit of thinking in throughput, unit cost, and bottlenecks. That is exactly the vocabulary needed to read the post-training series without hand-waving. Continue to 00 · Orientation, where the general data pipeline narrows into its specific post-training form.