🏗 Scale & System Design · Chapter 3
Event Time vs Processing Time
A driver in a tunnel sends her 8:59 PM ping at 9:04. Which hour does it belong to?
Study this lesson free in the app →
The basics
Event time is when something actually happened, stamped by the device that saw it. Processing time is when your system got around to handling it. In a demo they match; in production they can be seconds or hours apart.
The problem it solves: a driver in a tunnel pings at 20:59 and the ping reaches Kafka at 21:04. Count it by processing time and 9 PM demand looks higher than it was, 8 PM lower, and surge pricing reacts to a rush that already ended. Every wrong hourly or daily report traces back to someone quietly using the wrong clock.
The mental model: postcards from a holiday. Sort them by the date written on the card (event time) and the album is right, but you must decide how long to wait for stragglers before closing a page. That decision is the watermark. Wait longer and you are more complete but less fresh; close sooner and you are fresher but must correct later.
Words you must know 5
- Event time / ingest time / processing time
- happened / received / computed; keep all three
- Window
- a time bucket you aggregate over (tumbling, sliding, session)
- Watermark
- "no event older than T should still arrive"; usually max event time seen minus a delay
- Allowed lateness
- grace period in which late events still update a closed window
- Backfill
- recomputing past event-time partitions from raw data
Explained
Event time — when it actually happened, stamped by the producer.
Processing time — when your system finally saw it.
In a demo they are the same number. In production they differ by seconds, sometimes hours, and every wrong daily report traces back to someone quietly using the wrong one.
Postcards from a holiday
Friends post you postcards during a trip. Some take three days, one gets stuck in a sorting office for two weeks.
If you arrange them by the date written on the card, you reconstruct the holiday correctly — but you must decide how long to wait before declaring the album finished.
If you arrange them by the day they landed in your letterbox, the album is ready instantly and completely wrong.
Stream processing is that choice, made a million times a second. And watermarks are you saying: "anything posted before the 5th, I'll assume has arrived — I'm closing that page."
Windows, watermarks, allowed lateness
- Window — a bucket of time you aggregate over: tumbling (fixed, non-overlapping), sliding (overlapping), session (gap-based)
- Watermark — the engine's assertion that "no event older than T will still arrive". Usually
max_seen_event_time − allowed_delay - Allowed lateness — a grace period after the watermark during which late events still update a closed window
- Late/dropped data — arrivals past that grace period; route them to a side output rather than deleting them
The trade is stark and worth memorising: wait longer → more correct, less fresh. Close earlier → fresher, more corrections later. There is no setting that gives both.
The tunnel ping
event_time 20:59:02 ← when the driver was actually there
ingest_time 21:04:11 ← when Kafka accepted it
process_time 21:04:13 ← when your job handled it
window 20:00–21:00 aggregated by EVENT time → ping counted ✅
window 21:00–22:00 aggregated by PROCESS time → ping counted ❌
(9 PM demand overstated,
8 PM demand understated,
surge pricing misfires)Always carry all three timestamps into the lake. You cannot reconstruct them later, and the gap between them is your best latency metric.
Why lateness is normal, not exceptional
At scale, late data is not an edge case — it is the weather:
- Phones lose signal in tunnels, lifts, basements, rural roads
- Apps buffer offline and flush hours later
- A regional broker fails over and replays a backlog
- A consumer is redeployed and catches up on 40 minutes of lag
- A partner sends yesterday's file at 3 AM
So mature platforms do two things. The streaming layer serves a fast approximate answer for operations (surge, ETA, live ops). The batch layer recomputes the same window later from immutable raw data and produces the number finance uses. Same logic, two latencies, and the batch result wins on disputes.
That pattern has a name — lambda architecture in its classic form, and increasingly a single engine running both modes over one table format (Delta/Iceberg). Knowing why it exists matters more than the label.
Event time = when it happened. Processing time = when you found out.
Aggregate by event time. Alert by processing time. Keep both, plus ingest time.
Watermark = "I'm closing this page of the album."
Gotchas
- Trusting client clocks — phone clocks are wrong, sometimes deliberately. Keep the client's event time and a server-received time, and clamp absurd values instead of silently accepting a 2027 timestamp
- Timezones — store UTC, convert at the display edge. A daily report defined in IST that aggregates UTC days is off by 5.5 hours and nobody notices for a quarter
- Watermark too aggressive — silently drops real events. Always emit a metric for dropped-late-record count
- Backfills that overwrite by processing time — re-running yesterday must rebuild yesterday's event-time partitions, or you smear corrected data into today
- Ignoring out-of-order within a partition — Kafka preserves order per partition, but the producer may have buffered events out of order before sending
The question they ask
"Your streaming job reports 5,000 rides in the 8–9 PM window. The batch job reports 5,040 for the same window. Who is right?"
"Both, at their own moment. The streaming number closed at the watermark, so it excludes 40 events that arrived after the grace period — typically drivers reconnecting after signal loss. The batch job recomputed from immutable raw data hours later with all events present. Operations uses the streaming number because a 1% error in real time is fine for surge decisions; finance uses the batch number because it must reconcile. What I would check is whether the gap is stable at ~1% or growing, because a growing gap means my watermark is mistuned or a producer is systematically late."
That last sentence — turning a number into a monitoring question — is what separates 10-year answers from 2-year answers.
Words to know
| Event time | When the event occurred, stamped at the source. |
|---|---|
| Ingest time | When the platform received the event. |
| Processing time | When the job actually computed on the event. |
| Watermark | An engine's assertion that no event older than T will still arrive. |
| Allowed lateness | Grace period after the watermark in which late events still update a window. |
| Tumbling window | Fixed-size, non-overlapping time bucket. |
| Session window | A window defined by a gap of inactivity rather than a fixed clock. |
| Backfill | Recomputing historical partitions after a logic fix or late-arriving data. |
In two minutes
- Event time is when it happened, processing time is when you saw it; aggregate by event time.
- Keep event, ingest and processing timestamps in the lake — the gaps are your latency metric and cannot be rebuilt later.
- Windows bucket time: tumbling (fixed), sliding (overlapping), session (ends after a gap of inactivity).
- A watermark, usually max event time seen minus a delay, declares a window complete; later arrivals are late.
- Wait longer for more completeness, close earlier for freshness — no setting gives both. Route too-late events to a side output and count them.
- Late data is normal at scale: tunnels, offline buffers, failovers, consumer lag, partner files.
- Streaming gives a fast approximate number for operations; a batch recompute from raw gives the number finance trusts.
- Store UTC, define business days in the business timezone, and never trust client clocks blindly.
Test yourself
1. A ping created at 20:59 arrives at 21:04. Which window should count it?
- 21:00–22:00
- 20:00–21:00
- Both
- Neither — drop it
Show the answer
20:00–21:00 — Aggregate by event time, so it belongs to the 8 PM hour. Counting it at 9 PM would overstate 9 PM demand and understate 8 PM.
2. What does a watermark actually assert?
- That processing is complete
- That no event older than T is expected to arrive any more
- That the data is correct
- That the consumer has caught up
Show the answer
That no event older than T is expected to arrive any more — It is a heuristic completeness claim, letting the engine close a window. Being a heuristic, it is sometimes wrong — which is why you measure dropped late records.
3. Setting a very aggressive (short) watermark gives you…
- Fresher results, more dropped late events
- Slower results, perfect accuracy
- No change beyond memory use
- Guaranteed exactly-once
Show the answer
Fresher results, more dropped late events — The core trade: close earlier for freshness and lose stragglers, or wait longer for completeness and give up latency.
4. Streaming says 5,000 rides; batch recomputes 5,040. Most likely cause?
- A bug in the batch job
- Late events that arrived after the streaming watermark closed
- Duplicate events in batch
- The warehouse is out of sync
Show the answer
Late events that arrived after the streaming watermark closed — Batch runs later over complete immutable data, so it naturally captures stragglers. Worth checking the gap is stable rather than growing.
5. You want to group a rider's app activity into visits that end after 30 minutes of inactivity. Which window type is that?
- Tumbling
- Sliding
- Hopping
- Session
Show the answer
Session — Session windows are defined by gaps, not the clock, so each one has its own length. Tumbling windows are fixed and non-overlapping; sliding/hopping windows overlap at fixed intervals.
6. All events for driver d42 land on one Kafka partition and are read in offset order. Are they therefore in event-time order?
- Yes — Kafka guarantees order per partition
- No — the partition preserves the order they were *sent*, and phones buffer offline and flush out of order
- Only if the topic has a single partition
- Only with exactly-once enabled
Show the answer
No — the partition preserves the order they were *sent*, and phones buffer offline and flush out of order — Kafka orders by arrival at the broker. A phone that lost signal may send its 20:59 ping after its 21:03 ping, or retry an older batch. Order within a partition is a delivery guarantee, not an event-time guarantee — the stream job still has to handle disorder.
There are 8 questions, 3 puzzles and 5 recall cards for this lesson in the app — the recall cards come back on later days, just before you would forget.
Start this lesson →