Stateful operators and the state-size arithmetic
Why is state sized by the retention rule rather than the traffic?
An operator is stateful when its output depends on records that are no longer in flight. Those records, or a summary of them, must be retained. The central capacity question of this whole mechanism is: what are the retained bytes proportional to?
There are two regimes. Confusing them is the most common sizing error.
Key-bounded state
A per-key aggregation keeps one accumulator (a running total) per active key.
Time-bounded state
A stream-stream join keeps raw records for the whole join interval (Stream-stream joins).
Here state is rate × time. Doubling the traffic doubles the memory.
What follows
The cost of a streaming job is decided by which of the two regimes its operators belong to. A single interval join can be one to two orders of magnitude more expensive than every aggregation in the topology combined (here: 240 GB versus 5 GB is about 48×, and the gap grows with the window length). Sizing by throughput alone tells you nothing.
| Key-bounded | Time-bounded | |
|---|---|---|
| Example | count per user | stream-stream join |
| State grows with | number of active keys | rate × retention time |
| Traffic doubles → state | unchanged | doubles |
| Typical size in our example | 5 GB | 240 GB |