Kafka Streams Punctuate vs Process
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
In Kafka Streams, process handles incoming records one at a time, while scheduled punctuation handles work that should happen on a time boundary. If you mix those responsibilities, you usually end up with state stores that never flush at the right time or logic that runs only when new data arrives.
What process Does
The process method belongs to the Processor API and runs for each record delivered to the processor node. It is the right place for record-driven logic such as validation, enrichment, routing, counters, and state updates tied directly to an input event.
This code reacts only when a record arrives. If the topic is idle, nothing happens.
What Punctuation Is For
Punctuation is for scheduled work. In older discussions you will see the term punctuate; in current Kafka Streams code you normally schedule a Punctuator through context.schedule(...).
That scheduled callback is useful for tasks such as flushing aggregates, expiring stale entries, emitting heartbeats, or checking time-based windows.
Here, process collects input, and the scheduled callback decides when to emit.
Stream Time vs Wall-Clock Time
The scheduling mode matters.
STREAM_TIME advances only when records arrive. If the input topic is quiet, scheduled callbacks do not fire. Use this when your logic should be aligned with event progress.
WALL_CLOCK_TIME follows real elapsed time on the machine running the task. Use this for operational tasks such as periodic flushing or cleanup that should continue even during low traffic.
A lot of confusion comes from choosing STREAM_TIME and then expecting a callback every ten seconds of real time. That is not how it behaves.
How to Decide
Use process when the operation is about one record.
Use scheduled punctuation when the operation is about time, accumulated state, or maintenance.
Many processors need both: process to update state, and a scheduled callback to emit or prune that state. Separating those roles makes code easier to reason about and easier to test.
Common Pitfalls
- Expecting scheduled work to happen inside
processwithout new records arriving. Record-driven code is idle when the topic is idle. - Using
STREAM_TIMEwhen you really need wall-clock behavior. Quiet partitions then appear to "skip" punctuation. - Putting expensive batch work directly inside
process, which increases per-record latency. - Forgetting that punctuation usually acts on stored state, not on a current input record.
- Reading old examples that talk about overriding
punctuatedirectly without adapting them to the currentschedule(...)style.
Summary
- '
processis triggered by each incoming record.' - Scheduled punctuation is triggered by time, not by a specific input record.
- Use
STREAM_TIMEfor event-progress semantics andWALL_CLOCK_TIMEfor real elapsed time. - Many real processors combine both approaches cleanly.
- Choose the mechanism based on what should trigger the work, not on which method name sounds convenient.
Related reading
- Kafka Streams rebalancing latency spikes on high throughput kafka-streams services
- kafka streams session window retention duration
- Kafka streams shutting down and don't run
- Kafka Streams Sort Within Processing Time Window
- Kafka Streams (Suppress) Closing a TimeWindow by timeout
- Kafka Streams Testing java.util.NoSuchElementException Uninitialized topic output_topic_name
- Kafka Streams thread number
- Kafka Streams use case

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.