What Are Event Time and Processing Time?
Processing time is the wall-clock time of the machine executing an operator at the moment it handles a record; it has no relationship to when the event actually happened in the real world. Event time, by contrast, is a timestamp embedded inside the record itself, typically produced by the source system (a sensor, a mobile app, a Kafka producer) at the moment the event occurred. Flink can operate in either mode, but the two produce very different semantics when data arrives late or out of order.
Cricket analogy: A ball-by-ball commentary feed logged with the stadium clock in Mumbai (event time) tells you exactly when Virat Kohli hit a six, whereas the time your broadcast app rendered that update on your phone in London (processing time) depends on buffering and stream lag.
Why the Distinction Matters
Network delays, producer buffering, retries, and multi-region replication mean events routinely arrive at a Flink job out of order and later than when they occurred. If you window and aggregate purely by processing time, the same input replayed twice can land in different windows and produce different results, because the grouping depends entirely on when the cluster happened to see each record. Event time makes the computation deterministic and reproducible: replaying the exact same events, even at a different speed or on a different day, produces identical windowed results because the assignment of records to windows depends only on the timestamps carried in the data.
Cricket analogy: If you scored a match by when highlights reached your phone instead of by the actual over number, a rain-delayed broadcast could make a sixth-over six look like it happened in the tenth over — event time keeps the scorecard tied to the real over count regardless of broadcast delay.
Ingestion Time as a Middle Ground
Flink also offers ingestion time, where a source operator stamps each record with the wall-clock time at the moment it enters the Flink pipeline, right at the source. This avoids writing a custom timestamp extractor and sidesteps out-of-order data arriving from upstream producers, but it still shifts if the source itself experiences backpressure or restarts, and it cannot reconstruct the true moment an event happened outside the cluster. It is a pragmatic compromise used when the source system doesn't reliably embed usable event timestamps, but teams needing exact-once reproducibility on historical replays should prefer true event time.
Cricket analogy: If a stadium's PA system stamps every announcement with the time it reaches the loudspeaker instead of when the umpire signaled it, most delays are hidden, but a PA outage during a controversial DRS review still throws the announced timing off.
Configuring Event Time in the DataStream API
Since Flink 1.12, the DataStream API defaults to event time and the old StreamExecutionEnvironment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) call is deprecated and unnecessary. Instead, you assign a WatermarkStrategy directly on the stream, combining a timestamp extractor (which pulls the event-time field out of each record) with a watermark generator (which decides how much out-of-orderness to tolerate). Getting the extractor wrong — for example, extracting System.currentTimeMillis() instead of a field from the payload — silently degrades the pipeline into processing-time-like behavior even though the API still calls it 'event time.'
Cricket analogy: Configuring a scoring app to read the timestamp printed on the official scorecard, rather than the phone's own clock when the update notification pops up, is the equivalent of correctly wiring a timestamp extractor to the true event field.
DataStream<SensorReading> readings = env.fromSource(
kafkaSource,
WatermarkStrategy
.<SensorReading>forBoundedOutOfOrderness(Duration.ofSeconds(5))
.withTimestampAssigner((event, recordTimestamp) -> event.getEventTimeMillis()),
"kafka-sensor-source"
);
// Downstream windowing now operates purely on event.getEventTimeMillis(),
// not on when the record happened to be processed by this operator.
readings
.keyBy(SensorReading::getSensorId)
.window(TumblingEventTimeWindows.of(Time.minutes(1)))
.aggregate(new AverageAggregate());Since Flink 1.12, DataStream jobs use event time by default whenever a WatermarkStrategy is attached to the source; there is no separate 'mode switch' to remember, only correct timestamp extraction and watermarking.
If your timestamp assigner falls back to System.currentTimeMillis() instead of reading a field from the event payload, your job will silently behave like processing time even though every API call still says 'event time' — always verify the extractor reads the true event field.
- Processing time is the operator's local wall-clock time; event time is the timestamp embedded in the record when it actually occurred.
- Processing-time results are nondeterministic across replays because they depend on arrival order and cluster load, not the data itself.
- Event time makes windowed aggregations deterministic and reproducible, which is essential for correctness and for replaying historical data.
- Ingestion time stamps records at the moment they enter Flink, offering a pragmatic middle ground without a custom extractor.
- Since Flink 1.12, event time is the default mode once a WatermarkStrategy is attached to a source.
- A WatermarkStrategy combines a timestamp assigner (reads the event-time field) with a watermark generator (tracks out-of-orderness).
- Accidentally extracting a system clock value instead of the payload's timestamp silently degrades event time into processing-time behavior.
Practice what you learned
1. What distinguishes event time from processing time in Flink?
2. Why can processing-time aggregation produce different results when the same data is replayed?
3. What is ingestion time in Flink?
4. What happens if a WatermarkStrategy's timestamp assigner uses System.currentTimeMillis() instead of a payload field?
5. As of which Flink version does the DataStream API default to event time once a WatermarkStrategy is attached?
Was this page helpful?
You May Also Like
Watermarks
Learn how Flink watermarks track progress in event time, signal when a window can be closed, and balance latency against completeness.
Tumbling and Sliding Windows
Compare Flink's two fixed-size window types — non-overlapping tumbling windows and overlapping sliding windows — and when to use each.
Session Windows
Learn how Flink's dynamically-sized session windows group events by activity gaps rather than fixed clock boundaries, ideal for user-behavior analysis.
Allowed Lateness and Side Outputs
Learn how Flink handles data that arrives after a window has closed, using allowed lateness to permit late updates and side outputs to capture data that's too late.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics
ProgrammingPowerShell Study Notes
Programming · 30 topics