Skip to content
About
Main content

Summary and key takeaways

The inversion. Time stops being a cost to minimize and becomes metadata. Correctness means output that does not depend on how fast the pipeline ran. Any leak of execution speed into the answer is a bug.

The core constraint. Completeness is unobservable, because silence is ambiguous. So every time-based result is a bet. The three ways to pay: wait (latency), guess (accuracy), revise ( must accept edits).

Three clocks, one non-clock

ClockProperty
Meaningful, unverifiable (device clocks are adversarial)
Always present, meaningless, the only one that breaks reproducibility
Trustworthy and replayable, but turns your outages into facts about the world
()No clock; gap-free order; drives progress, and replay

The skew distribution (processing − event) has a median near your latency and a tail 10⁴–10⁵ times larger. Every waiting decision is a choice.

Watermarks. A declared lower bound on future event times. Perfect only if the source proves its order; otherwise max observed − δ, where δ is a (each extra nine multiplies the wait). Across it is a min. need a timeout, which is a conscious trade of correctness for liveness and needs an alarm. Watch and separately.

Late data. Drop (count it), divert, or re-fire. sets state retention: retained ≈ 1 + lateness / windowSize. is not completeness.

Disorder. Bounded disorder K costs O(K) memory. , operators need no buffer at all.

Triggers. , on-time, late. (total vs delta) must match the : overwrite or additive.

Partitioning. Event-time partitions turn a query problem into a maintenance problem; ingestion-time partitions do the opposite. Use both, and publish the freeze horizon.

Revision. Output edits need a key ( pairs or ). Computation revision needs an inverse: sum and count have one; max, min, exact distinct and exact percentiles do not.

Bitemporality. and are independent. A correction is a new rectangle, not an update. Type-2 SCD is only the valid-time half. is only per-table and only transaction time.

Temporal joins. Say as of when. Join against the version valid at the event time, or you leak the future. The correct plan is more expensive than the wrong one.

Calendars and clocks. Store the instant plus the zone name. Local time has duplicates and gaps. are not durations. Durations use the . A run's logical time is an input, never an ambient read.

TTL. Expiry redefines guarantees: exactly-once exists only within a de-duplication horizon. Keep dedup ≥ replay/retry horizon ≥ allowed lateness ≥ δ.

Formulas and rules worth remembering:

FormulaMeaning
watermark = max observed event time − δ; δ is a quantile
global watermark = min over partitionsOne slow input freezes everyone
retained windows ≈ 1 + lateness / window sizeCost of completeness in state
interval-join memory ∝ w × combined rateWindow width is both meaning and memory
dedup TTL ≥ replay horizon ≥ lateness ≥ δThe chain nobody checks

Patterns that repeat:

  • You cannot observe completeness; you declare it and price the error.
  • Costs are conserved: latency, accuracy, or the consumer pays.
  • Retained state is the one currency: lateness, replay depth, time-travel horizon and TTL are one knob.
  • Collapsing two independent axes into one loses information at write time, permanently.
  • The cheap plan is often the wrong one (current-version joins, ingestion-time partitions, wall-clock timeouts).