Deep dive · Part 4 · supplement to Lesson 8 · visual edition

Watermarks — the completeness clock of streaming

~25 min · 5 levels · 3 reused diagrams + new SVGs · interview Qs · interactive recall

Published

WatermarksEvent-time windowingEvent drivenExactly onceStreaming

Your bar: redraw — from memory — why a watermark is a guess, how it advances by a min rule, why one idle input freezes a whole pipeline, and the Dataflow-model insight that when a window fires is not the watermark. Grounded in Akidau et al.’s Dataflow Model 1 and the Flink/Beam docs. 3

One sentence holds the whole topic. Each level just unpacks one chip of it:

A watermark is a heuristic completeness claim in event time

that advances by the min of its inputs

trading completeness vs latency vs cost

and it informs, never decides, when a window fires

THE TWO CLOCKS — event time vs processing time processing time (when you saw it) → event time ↑ ideal: event time = processing time watermark W (a lagging lower bound) late! (below W → would be dropped) on-time events arrive scattered, out of order skew = how far W lags reality
Memorise this banner. Events happen in event-time order but arrive out of order; the watermark W is a moving lower bound chasing completeness — and the gap is skew.
1

What a watermark actually asserts

Strip the metaphor: it is one timestamp carried with the data, making a claim about completeness.

event time → e1 e2 e3 e4 W marker in the stream ✓ claimed COMPLETE: no future record ≤ W not yet claimed (> W) W is a monotonic, non-decreasing lower bound on all FUTURE timestamps
W asserts: "event time has advanced to W — no record with timestamp ≤ W arrives from here on." It turns "have I seen all of 12:00–12:05?" into a concrete signal.

Is A single timestamp carried with the data: a monotonic lower bound on every future record’s event time.

Why it exists To convert the open-ended “have I seen all the data for this window yet?” into one concrete completeness signal.

Like (world) A “mail through <date> has all been delivered” stamp — letters dated earlier won’t show up after it.

Like (code) A timeout for failure detection: a heuristic the system commits to because it can’t wait forever for certainty.

✗ “A watermark is the current processing-time clock”

✓ It’s an event-time lower bound — a claim about completeness, not wall-clock now

💧 Memory rule: A watermark is a timeout for completeness — a monotonic lower bound asserting no future event ≤ W will arrive.

Memory check
  • What does W claim, precisely? → no future record will have timestamp ≤ W
  • Monotonic means? → it only ever moves forward, never back
  • Closest reliability primitive? → a timeout — a committed-to heuristic, not a fact
2

Perfect vs heuristic — the tension that defines streaming

Perfect is rare and clean; heuristic is what you actually run, and it’s wrong in one of two ways.

Perfect vs heuristic watermarks. A perfect watermark never passes an unseen event, so nothing is ever late. A heuristic watermark is a guess: set it too fast and real events arrive late and get dropped; too slow and windows fire late while state piles up.

Perfect vs heuristic watermarks. Perfect never passes an unseen event, so nothing is ever late. Heuristic is a guess — too fast and stragglers drop; too slow and windows fire late while state piles up.

Perfect Needs perfect knowledge of timestamps (in-order partition, hard max delay). Exact → never any late data. Rare.

Heuristic Estimates progress, usually “max timestamp seen − bound B” (bounded-out-of-orderness). Being an estimate, it errs.

If the watermark is…Then…You lose
too fast (aggressive)passes window-end before stragglers arrive; those events are now “late”completeness — late data dropped
too slow (conservative)lags real progress; windows fire long after their data is inlatency — results delayed, state held longer
✗ “Just set the watermark correctly”

✓ It’s a policy; there is no setting that wins both — only one matched to how late your data runs

⚖️ Memory rule: A watermark trades completeness against latency — advance eagerly and drop stragglers, or conservatively and pay in delay and state.

Memory check
  • When is a perfect watermark possible? → in-order source or a known hard max delay
  • The common heuristic generator? → max-seen timestamp minus a bound B
  • Too-fast costs ___, too-slow costs ___? → completeness; latency (+ state)
3

The min rule — and the idle-partition stall

Watermarks flow as markers between operators. One propagation rule causes the most common streaming incident.

The min rule and the idle-partition stall. An operator's watermark is the minimum across its inputs. If one partition goes idle, its watermark stops advancing, pins the minimum, and every downstream window freezes even though data is flowing on the other inputs.

The min rule & the idle-partition stall. An operator’s watermark is the minimum across its inputs. One idle partition pins the min and freezes every downstream window — even while the other inputs flow.

output W = MIN(inputs) — the slowest input governs in A · W=14:05 ▲ in B · W=14:07 ▲ in C · W=13:40 ✗ idle operator W = min(...) W pinned to 13:40 ✗ downstream windows freeze withIdleness ✓ exclude C → W = 14:05
A quiet input's stale watermark pins the min "forever or until it gets data." The dashboard shows records flowing yet nothing emitted — stalled, no error.

Rule An operator’s watermark = minimum of all input watermarks (held back further by buffered state with pending timers).

Why min You can’t claim “complete up to W” if even one input might still deliver something older than W.

The stall An idle input stops advancing → pins the min → downstream windows never fire. The classic silent streaming incident.

The fix Idleness detection: after a quiet period, mark the source idle and exclude it from the min; re-include on first record. 3

✗ “Pipeline emits nothing → it must be crashing or back-pressured”

✓ Often a watermark held hostage by one silent input; fix is withIdleness, not a restart

🧊 Memory rule: An operator’s watermark is the min of its inputs — so one idle partition freezes the whole pipeline until idleness detection excludes it.

Memory check
  • How does an operator's watermark advance? → as the minimum of all its input watermarks
  • Why the min, not the max or average? → the slowest input could still deliver old data
  • One idle partition's symptom + fix? → silent stall; withIdleness to exclude it
4

Triggers — when to fire is not the watermark

The deepest idea, from the Dataflow Model: three questions everyone conflates are actually independent.

WHERE in event time? → windowing WHEN in processing time? → triggers HOW do results relate? → accumulation THREE INDEPENDENT QUESTIONS — the watermark only INFORMS the middle one the watermark does NOT decide when a window fires
Where → windowing · When → triggers · How → accumulation. The watermark informs the on-time firing; it does not answer "when".
Triggers decouple firing from the watermark. A window can fire EARLY (speculative partial results before the watermark), ON-TIME (when the watermark passes window-end), and LATE (again when stragglers arrive within allowed lateness), then its state is dropped and truly-late data is discarded.

Triggers decouple firing from the watermark. A window can fire EARLY (speculative), ON-TIME (when W passes window-end), and LATE (again, as stragglers arrive) — so a trigger fires more than once.

Accumulation modeEach firing emitsDownstream must
Discardingonly what’s new since the last firing (a delta)sum the deltas itself
Accumulatingthe full result-so-far (overwrites the previous)replace the prior value
Accumulating + retractinga retraction of the old value plus the new oneapply both for exactness
✗ “The watermark fires the window, exactly once”

✓ The trigger fires — early, on-time, and late; the watermark only informs the on-time firing

🎯 Memory rule: Windowing = where, triggers = when, accumulation = how — so late data isn’t a guillotine; the window re-fires and corrects.

Memory check
  • The three independent questions? → where (windowing), when (triggers), how (accumulation)
  • How many times can a trigger fire? → many: early, on-time, late
  • Why isn't late data a problem here? → late firing + accumulating mode corrects the result
5

Allowed lateness — and the three-way trade-off

Late firings can’t run forever. Allowed lateness is the horizon, and the third dial.

A WINDOW'S LIFETIME W passes end state GC'd allowedLateness → late firings update result on-time after GC → truly late → side output / dead-letter (never silently) side out THREE DIALS completeness latency cost pick two, pay the third
After W passes window-end, state is kept for allowedLateness; late events re-fire within it. Past the horizon, state is GC'd and truly-late events route to a side output.

Allowed lateness The extra duration a window keeps its state after W passes its end; late events within it re-fire.

After the horizon State is garbage-collected; later events are truly late → drop or route to a side output / dead-letter.

Fire early Lower latency, less complete. Wait for W → more complete, higher latency. Hold state longer → tolerate lateness, at memory cost.

Dials Watermark, triggers, allowed-lateness set completeness vs latency vs cost. You can’t max all three.

✗ “Late data is just dropped and lost”

✓ Within allowed lateness it re-fires; past it, route to a side output — never silently, if you value your data

🎚️ Memory rule: Completeness vs latency vs cost — the three dials are watermark, triggers, and allowed lateness; pick the two your use case needs.

Memory check
  • What is allowed lateness? → how long state is kept past window-end for late firings
  • What happens to truly-late events? → drop or route to a side output / dead-letter
  • The three dials of the trade-off? → watermark, triggers, allowed lateness

Same primitives, opposite dials — by workload

Grounding: the same windowing primitives, set to opposite ends, for different jobs. This per-workload judgement is the whole point.

WorkloadWantsDial settings
Fraud checkLow latency; tolerates re-firing & correctionaggressive watermark · early + late firings · short state
Billing rollupCompleteness; accepts delayconservative watermark · on-time firing · long allowed lateness
Live dashboardFast, improving estimatefrequent early firings · accumulating mode · modest lateness
Exact financial sumCorrectness across late updatesaccumulating + retracting · long allowed lateness · side output for the rest
Multi-source joinNot freezing on a quiet input

withIdleness on every source · watch the min

Pattern to notice: the dials don’t change the engine — they change which of completeness, latency, and cost you pay for. Naming that trade-off out loud is the senior move. 2

Retrieval practice — mix the levels

Reading builds fluency (feels familiar). Recall builds storage (lasts). Answer from memory — instant feedback.

Q1. A watermark W flowing through a pipeline asserts that…

Q2. A heuristic watermark set too fast (too aggressive) costs you…

Q3. A pipeline emits nothing despite healthy input because one partition went idle. The cause is…

Q4. In the Dataflow model, what decides when a window emits a result is the…

Q5. Allowed lateness primarily controls…

Q6. "Accumulating + retracting" mode is needed when downstream…

Reconstruct the topic from a blank page

Write the five levels in order, one line each, with nothing on screen. Then reveal and compare — gaps are your next drill.


1 Watermark = monotonic lower bound; no future event ≤ W (a timeout for completeness) · 2 Perfect (rare, no late data) vs heuristic (a guess; too fast drops, too slow lags) — completeness vs latency · 3 Operator W = min(inputs); one idle input stalls everything → withIdleness · 4 Where=windowing, When=triggers (early/on-time/late, many times), How=accumulation; watermark only informs · 5 Allowed lateness keeps state for late firings, then GC + side output; dials = completeness/latency/cost.

I’m your teacher — ask me anything. Say “grill me on watermarks” for mixed no-clue questions, or drop a real pipeline and I’ll set its watermark / trigger / allowed-lateness dials with you on the completeness↔latency↔cost triangle. Want a spaced, interleaved drill set? Just ask.

Interview — pick your bar

Answer out loud in ~60s, then reveal. Core = recall · Senior = trade-offs & failure modes · Staff = synthesis under ambiguity · System Design = open design round (a different axis, not a harder level).

Event time vs processing time — define each and why they diverge.
Hits: event time is when the thing actually happened (stamped at the source); processing time is when the record reaches the operator's wall clock. They diverge because of buffering, network delay, retries, and replay — arrival lags origin, unboundedly and out of order. Bucket by event time for reproducible, replay-stable results; processing time is only acceptable when you don't care about correctness under delay.
Define a watermark precisely, and say why it's like a timeout.
Hits: a single, monotonic, non-decreasing timestamp carried with the data; asserts no future record will have event time ≤ W. It's a heuristic the system commits to because it can't wait forever for certainty — exactly like a timeout for failure detection. Red flag: confusing it with the processing-time clock.
Name the window types — tumbling, sliding, session — and what each is for.
Hits: tumbling = fixed-size, non-overlapping buckets (each event in exactly one) — periodic aggregates. Sliding = fixed-size but overlapping by a step, so an event lands in several windows — moving averages. Session = dynamic, data-driven windows bounded by a gap of inactivity, so window length varies per key — user activity bursts. The first two are aligned to the clock; sessions are defined by the data.
What is allowed lateness, and what happens to data past it?
Hits: allowed lateness extends how long a window's state is kept after the watermark passes its end, so late stragglers can still re-fire and correct the result. Once lateness is exceeded the state is dropped — events arriving after that are "truly late" and should be routed to a side output / dead-letter, never silently discarded. It is the dial trading memory/state lifetime against completeness.
Perfect vs heuristic watermark — when can you have a perfect one, and what does it buy?
Hits: perfect requires perfect knowledge of timestamps — an in-order single partition or a hard, known max delay; then there is never any late data. Heuristic estimates (max-seen − bound B) and is wrong in one of two directions. Bonus: most real sources are heuristic, so design for late data.
Your pipeline is processing records but emitting nothing, with no error. Diagnose.
Hits: an operator's watermark is the min of its inputs; a silent/idle partition's stale watermark pins the min and freezes every downstream window. Fix: idleness detection (withIdleness / idle-source handling) to exclude the idle input, re-include on first record. Not a crash, not back-pressure.
Why is the propagation rule a MIN and not a max or average?
Hits: the watermark is a completeness claim; you cannot assert "complete up to W" on the output if even one input might still deliver something older than W. The slowest input governs. Bonus: buffered state with pending event-time timers can hold it back further.
"But what about late data?" — answer it without dropping anything.
Hits: with late-firing triggers + an accumulating (or +retracting) mode, a straggler arriving after W re-fires the window and corrects the result. Allowed lateness bounds how long state is kept; past it, route truly-late events to a side output / dead-letter — never silently. The watermark stops being a guillotine and becomes a completeness estimate.
Separate windowing, triggers, and accumulation. Where does the watermark fit?
Hits: windowing = where in event time data is grouped; triggers = when output is emitted (early/on-time/late, possibly many times); accumulation = how successive results relate (discarding / accumulating / +retracting). The watermark only informs the on-time firing — it does not decide when the window fires. This is the Dataflow Model's core insight.
Argue that there is no "correct" watermark setting.
Hits: a watermark trades three axes that cannot all win — completeness (wait for stragglers), latency (fire early), and cost (state held open). An aggressive watermark fires fast but drops/corrects more; a conservative one is complete but slow and memory-hungry. So the "right" setting is a business choice about which failure you tolerate, not a property of the data. Staff signal: the candidate ties the setting to a downstream SLA, not to a default.
How do triggers, allowed lateness, and accumulation mode interact to give correct-but-eventually-consistent output?
Hits: the trigger may fire early (speculative), on-time (at the watermark), and late (per straggler within allowed lateness); accumulation mode decides whether each firing replaces, adds to, or retracts-and-replaces the prior result. Together they let a window emit a fast approximate answer and converge to the complete one as late data arrives — the streaming analogue of eventual consistency. Allowed lateness is the cutoff after which convergence stops and state is reclaimed.
System Design — what a strong design round demonstrates:
  1. Anchor on event time, not processing time, and explain why (reproducibility under replay and out-of-order arrival).
  2. Pick the window type from the question (tumbling / sliding / session) and justify it.
  3. Choose a watermark strategy (perfect vs heuristic; the bound B) and place it on the completeness↔latency↔cost triangle.
  4. Decouple triggers (when to fire: early / on-time / late) from the watermark, and choose an accumulation mode.
  5. Set allowed lateness and route truly-late data to a side output — never drop silently.
  6. Handle idle / skewed inputs (min-rule freeze) with idleness detection.
  7. Name the observability: watermark skew, dropped-late count, window state size.
Design event-time windowing for an out-of-order stream (e.g. mobile clients with intermittent connectivity).
A strong answer covers: stamp event time at the source and key by user/device; pick the window type to the metric (tumbling for periodic counts, session for activity bursts); a heuristic watermark with a bound B sized to observed lateness; triggers that fire early for a live estimate, on-time at the watermark, and late within an allowed-lateness budget, with an accumulating-or-retracting mode so results converge; truly-late events sent to a side output for reconciliation; idleness detection so a quiet device doesn't freeze the min watermark; and explicit monitoring of watermark skew and late-drop rate. The candidate should frame the dials as a completeness/latency/cost choice tied to the SLA.
Design a monthly billing rollup vs a real-time fraud signal on the same event stream.
A strong answer covers: the same primitives, opposite dials. Billing: a conservative watermark, on-time firing only, long allowed lateness and durable state → completeness over speed, accepting latency and memory, with reconciliation against a side output before close. Fraud: an aggressive watermark, early + late firings, short state and an accumulating/retracting mode → low latency, tolerating corrections. The candidate names completeness vs latency vs cost as the governing trade-off and maps each workload to a point on it, rather than reaching for one "correct" configuration.

★ Cheat sheet — term → what it actually is

Mental models: Watermark = a timeout for completeness · Perfect = never late, rare · Heuristic = a guess, too-fast drops / too-slow lags · Min rule = slowest input governs · Idle stall = silent freeze, fix with idleness detection · Triggers = when (many times) · Accumulation = how firings relate · Allowed lateness = how long state lives.

Translation table

TermWhat it actually is
Watermark WMonotonic lower bound: no future event ≤ W
SkewHow far W lags true event-time progress
Perfect vs heuristicExact (no late data) vs estimated (late data happens)
Min ruleOperator W = min(input watermarks); slowest governs
Idle-partition stallSilent input pins the min → downstream freezes
Trigger

Decides when to emit: early / on-time / late

Accumulation modeDiscarding / accumulating / +retracting
Allowed latenessHow long window state survives for late firings
Side outputWhere truly-late events go (a dead-letter)

Three rules for the on-call chair

① A watermark is a guess, not a fact — a timeout for completeness. ② An operator’s watermark is the min of its inputs; one idle input freezes everything — reach for idleness detection. ③ When a window fires is the trigger, not the watermark — so late data corrects, it doesn’t have to drop.

★ Review guide & what to read next

5-min (weekly) Don’t re-read — recall. Say the one sentence; redraw the two clocks + the min rule from memory; recite the five rules; name the three dials blind.

30-min (when stalled) Blank-page reconstruct all five levels; re-derive why min is forced and why triggers must decouple from the watermark; then set the dials for one real pipeline of your own.

Read next, in order:The Dataflow Model — Akidau et al., VLDB 2015 (Level 4, read first) · ② Streaming 101 / 102 — Akidau (the watermark intuition) · ③ Flink — Generating Watermarks & idleness (Level 3) · ④ Beam — triggers & accumulation (Level 4–5).

📖 Primary source: Streaming Systems (Akidau, Chernyak & Lax, O’Reilly 2018) — the definitive treatment of watermarks and triggers.

Sources
1. Akidau, Bradshaw, Chambers, Chernyak, Fernández-Moctezuma, Lax, McVeety, Mills, Perry, Schmidt & Whittle, The Dataflow Model (VLDB 2015) — separated windowing, triggering, and accumulation.
2. Akidau, Chernyak & Lax, Streaming Systems (O'Reilly, 2018), and "Streaming 101/102" — the definitive treatment of watermarks & triggers.
3. Apache Flink documentation — Generating Watermarks, WatermarkStrategy.withIdleness, allowed lateness, side outputs; and Apache Beam — windowing, triggers, accumulation modes, late data.
4. Kleppmann, Designing Data-Intensive Applications, Ch. 11 — event time vs processing time; "when is a window complete?"
Was this lesson helpful? Thanks — noted.

These notes reflect my current understanding and are updated as I learn, build, and discover better explanations.