Make the right trade-off / CHAPTER 39
Batch versus stream processing
Choose data-processing boundaries by result freshness, event timing, recovery, and cost.
Builds on Back-of-the-envelope estimation, Synchronous versus asynchronous communication.
- Explain bounded inputs and continuous computation.
- Distinguish event time from processing time.
- Handle late and duplicate events explicitly.
01When is the input complete?
A shop needs both yesterday's final sales report and a warning when suspicious purchases occur within seconds.
- A batch job processes a fixed input, such as yesterday's saved files or database snapshot, then finishes.
- A stream processor keeps handling an ongoing sequence of arriving sales and updates results as new records appear.
Batch can simplify large scans, checking totals and rerunning the same fixed input. Streaming provides earlier results but needs saved calculation state, progress tracking and rules for delayed data.
Neither is automatically complete or accurate. A batch misses sales if its source files are missing. A live total can look current while offline devices have not uploaded their sales. Streaming may use small internal batches; that implementation detail does not turn ongoing input into a final closed dataset.
02Time and state are part of correctness
A device records sale S9 at 12:00 but uploads it at 12:07. Separate the two clocks:
- Event time is when the sale occurred according to its timestamp: 12:00.
- Processing time is when the processor handles the record: around 12:07.
- A window groups sales into an interval, such as 12:00–12:05. If the report means sales occurring then, late
S9belongs in that interval, not the interval when its upload arrived. - A watermark estimates how far event-time input has progressed. Passing 12:05 can let the processor publish a result under its assumptions, but does not prove an older device upload cannot appear later.
- Declare late-data handling. Revise the original interval for an allowed period, create a separate adjustment, or close it under a stated rule. Tell users whether the number is preliminary or final.
| Choice | Batch | Stream |
|---|---|---|
| Input | A fixed file, snapshot or selected range. | An ongoing sequence. |
| Result | Returned after bounded work finishes. | Updated incrementally as records arrive. |
| Recovery | Rerun or resume the fixed computation. | Restore saved state and replay input from a matching position. |
| Completeness risk | Missing or delayed source data. | Delayed, repeated and reordered records. |
Keep the same definition of a valid sale in both paths; otherwise comparing their totals does not reveal which one is wrong.
03Worked example: sales analytics
Assume 2,000 sales/s. A day contains 2,000 × 86,400 = 172.8 million events. At 200 bytes each, that is 34.56 GB/day raw, before copies, indexes and logs. Keep enough input to support required replay and checking.
Follow S9 through a five-minute revenue view:
- Save the original sale facts. Retain sale ID, event time, amount and relevant version in replayable input.
- The processor chooses
S9's event-time window. It adds the sale to the corresponding preliminary total and writes a new result version. S9arrives at 12:07 for 12:00–12:05. For this example, accept corrections until ten minutes after the window ends, using the processor’s clock: 12:15 for this window. The 12:07 arrival therefore changes the original total. Do not count it as a sale occurring at 12:07.- A repeated
S9must not add revenue again. For a transactional output, a unique applied-sale/window record can be checked and saved with the total update. The processor checks the sale/window key; if absent, it inserts that key and increases the total in the same transaction. If present, it skips the increment. A unique key prevents concurrent attempts from both succeeding. Other processing engines need an equivalent rule covering both repeat recognition and the output change. - The worker crashes. Restore calculation state and its matching saved input position, then replay. An output already written just before the crash may repeat, so protect the destination too; checkpointing input alone is insufficient.
One million active shop/window keys at 200 bytes each need 200 MB of raw working state. Engine storage, checkpoints and overlapping windows add more. A small final chart does not imply a tiny processing system.
A nightly batch can check a closed reporting interval:
- Read a saved stream checkpoint containing the interval’s total, the last included input position and its result version. That position is the batch’s input cutoff; that result version is its baseline version. Comparing different input cutoffs could mistake unprocessed sales for a counting error.
- Recompute that interval from saved sales through the same cutoff. Give the correction a stable identity made from the interval, input cutoff and baseline version—not the checking job’s run ID.
- In one database transaction, check whether that correction identity was already applied and whether the target total still has the baseline version and cutoff. If already applied, return the recorded result. If the target advanced, leave it unchanged and recompute against a newer checkpoint.
- If both checks allow the change, replace the total with the checked total, increase its result version and save the applied-correction record together. Do not add the whole checked total as another sale. Two checking runs using the same baseline therefore cannot apply it twice.
- Stream updates must use the same result-version check. If a correction changed their baseline, they reload the corrected total before adding the next sale; they cannot overwrite it with an old absolute total. The stream can continue processing other intervals while this check runs.
Batch versus stream processing — decision flow
Follow the numbered arrows
- Saved sale log → Stream processorread arriving sales continuously
- Stream processor → Live revenue viewsave a newer preliminary total
- Saved sale log → Batch checking jobread the selected fixed interval
- Batch checking job → Checked totalsrecompute and check saved sale totals
- Checked totals → Live revenue viewpublish the checked total only if its baseline still matches
Trace the diagram in words
- Read saved sale facts through both the quick updating path and the fixed checking computation.
- Assign late sales to their intended interval and recognize repeated sales before changing totals.
- Compare the same input cutoff; atomically check the baseline version and correction identity before publishing a checked total.
04Often the right answer combines them
Choose freshness and completeness deliberately:
- Use batch when periodic completion is acceptable and rerunning fixed input is valuable.
- Use streaming when prompt alerts or continuously changing results justify ongoing state and recovery work.
- Combine them when both paths use the same business definition: one gives an early view and the other checks completeness.
- Explain “exactly once” with participants. Saved input position, calculation state and outputs must agree. A transaction inside a message system does not automatically include an email or payment provider.
- Measure delay and drift. Track how far processing trails input, oldest unprocessed age, event-time progress, late arrivals and differences found during reconciliation.
In an interview, trace a normal sale, a late sale and a repeated sale after a crash. Name the actual record preventing double counting and when users may rely on the total as final.
DRAW. CALCULATE. EXPLAIN.
Explain one late sale
20 minutes · guided practice
A sales log carries 1,000 events/s at 300 bytes/event. A sale at 09:02 arrives at 09:09, after a preliminary 09:00–09:05 total. For this exercise, corrections are accepted until ten minutes after the window ends, measured by the processor’s clock. Compute daily raw input and trace late correction, duplicate replay and crash recovery.
Compare the worked solution
- A day contains 1,000 × 86,400 = 86.4 million events. At 300 bytes each, raw input is 25.92 GB before overhead and copies.
- The 09:02 sale belongs to 09:00–09:05 even though it arrives at 09:09. Correct that total under the ten-minute rule and publish a newer result version.
- Save recognition of the sale with the output change, or use an equivalent repeat-safe destination, so replay cannot add it again.
- Restore calculation state and a matching input position after a crash, then replay through that same output rule.
- The direct correction period ends at 09:15. Keep a later sale as a separate adjustment for the checking job rather than silently dropping its revenue. A fast preliminary number is not automatically complete.
The checkboxes record your own assessment. The worked solution gives you a way to check the reasoning.
RETRIEVE BEFORE YOU REVEAL
Keep the important ideas.
Say the answer aloud, then turn the card over.
CARD 01What makes batch and streaming different?
- A batch computes over fixed input and finishes.
- A stream keeps processing arrivals.
- State when results appear and count as complete; small internal batches do not remove ongoing-input recovery needs.
CARD 02How is a late sale counted?
- Keep its occurrence time separate from processing time.
- Correct its intended interval within the declared lateness rule.
- A watermark estimates progress; it does not prove no older event can arrive.
CARD 03What must stream recovery coordinate?
- Restore calculation state and matching input position.
- Replay safely.
- The destination recognizes already-applied sales or shares a coordinated commit, so an output written before the crash is not counted twice.
CHECK THE REASONING
Can you explain the choice?
Answer every question, then finish for an immediate score and an explanation for each answer. Aim for 80%, then revisit any gaps.
CLOSE THE LOOP
Explain it without the page.
Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.