Stream-Processing Runtime Performance
Purpose
Turn a streaming symptom into the runtime resource, state or recovery mechanism that owns it.
Kafka Streams is an embedded partition-to-task library; Flink is a distributed operator graph.
They share concepts but not a tuning surface.
Common contract
Record engine and connector versions, topology/job graph, input partitions and key distribution,
operator/task parallelism, offered/completed events and bytes, per-partition age/lag, backpressure,
state location/size, allocation rate, heap/RSS/container limits, checkpoint/commit configuration,
processing guarantee, sink visibility and recovery objectives.
Inspect the project's JDK/toolchain and engine/connector support matrix; the references use Kafka
4.0 and Flink 2.0 as evidence baselines, not mandatory upgrades. Preserve topology IDs, partitioning,
state schemas and deployment authority when changing runtime settings.
Workflow
- Draw source partitions through every shuffle/operator to state and sinks. Mark ownership,
serialization and atomic recovery boundaries.
- Locate the limiting partition or operator with aligned rates, waits and resource evidence; aggregates hide skew and head-of-line
blocking.
- Separate durable backlog from runtime backpressure. Kafka lag can grow without slowing producers;
Flink operator credit/backpressure propagates within the job graph.
- Reconcile declared and effective configuration from runtime APIs/logs. Deprecated keys may warn;
unknown keys may be ignored.
- Account for heap allocation and native/file-backed state separately inside the same container.
- Change one evidenced parallelism, state, checkpoint or sink variable and validate steady state plus failure,
restore and rescale behavior.
Rules
- Size Kafka partitions from measured per-partition producer and consumer capacity plus growth and
failure headroom; powers of two or broker multiples are placement heuristics, not laws.
- Size Flink per operator. Raising global parallelism cannot repair one serialized sink, skewed key
or blocking call.
- Exactly-once has a declared boundary. External effects outside the engine transaction/checkpoint
need idempotency, fencing or their own transaction protocol.
- Checkpoint success is not automatically sink visibility. State when a two-phase sink commits and
include that delay in the output-latency contract.
- State size does not determine Java heap by itself. Allocation, retained live state and object
lifetimes affect GC; RocksDB caches/write buffers and file pages have distinct native/resident
accounting. Managed memory is a budget, not an additional RSS category to sum twice.
- Backpressure is a symptom location, not necessarily the root. Walk downstream to the first
operator whose output capacity degrades without an upstream cause.
- Busy task time is not CPU utilization: blocking callbacks and chained operators need stack,
I/O and downstream evidence. Healthy throughput with stalled watermarks can instead be an
event-time/idleness problem; do not add parallelism solely because a window emits nothing.
- Return the localized observation, competing cause, effective settings, bounded change and
steady/recovery validation. Missing metrics or failed experiments remain inconclusive; measure
successful visible results as well as input consumption, dropped events and retries.
References
- Kafka Streams operation — read for task/partition capacity,
transactions, state stores, standby replicas or commit visibility.
- Flink operation — read for operator backpressure, checkpoints, RocksDB,
watermarks, savepoints or connector lifecycle.
1---2name: stream-processing-runtime-performance3description: Operating Kafka Streams and Apache Flink for predictable throughput, state and recovery: separating their execution models, sizing partitions or operator parallelism, diagnosing backpressure, bounding native state, and relating commits or checkpoints to result visibility. Use when one partition or operator limits a pipeline, checkpoints grow or stall, RocksDB drives RSS outside the heap, exactly-once changes latency, or effective runtime configuration differs from declared settings. Generic topology and event-time semantics belong to streaming-pipeline-topologies; plain Kafka consumer loops to kafka-consumers-in-java.4---56# Stream-Processing Runtime Performance78## Purpose910Turn a streaming symptom into the runtime resource, state or recovery mechanism that owns it.11Kafka Streams is an embedded partition-to-task library; Flink is a distributed operator graph.12They share concepts but not a tuning surface.1314## Common contract1516Record engine and connector versions, topology/job graph, input partitions and key distribution,17operator/task parallelism, offered/completed events and bytes, per-partition age/lag, backpressure,18state location/size, allocation rate, heap/RSS/container limits, checkpoint/commit configuration,19processing guarantee, sink visibility and recovery objectives.20Inspect the project's JDK/toolchain and engine/connector support matrix; the references use Kafka214.0 and Flink 2.0 as evidence baselines, not mandatory upgrades. Preserve topology IDs, partitioning,22state schemas and deployment authority when changing runtime settings.2324## Workflow25261. Draw source partitions through every shuffle/operator to state and sinks. Mark ownership,27 serialization and atomic recovery boundaries.282. Locate the limiting partition or operator with aligned rates, waits and resource evidence; aggregates hide skew and head-of-line29 blocking.303. Separate durable backlog from runtime backpressure. Kafka lag can grow without slowing producers;31 Flink operator credit/backpressure propagates within the job graph.324. Reconcile declared and effective configuration from runtime APIs/logs. Deprecated keys may warn;33 unknown keys may be ignored.345. Account for heap allocation and native/file-backed state separately inside the same container.356. Change one evidenced parallelism, state, checkpoint or sink variable and validate steady state plus failure,36 restore and rescale behavior.3738## Rules3940- Size Kafka partitions from measured per-partition producer and consumer capacity plus growth and41 failure headroom; powers of two or broker multiples are placement heuristics, not laws.42- Size Flink per operator. Raising global parallelism cannot repair one serialized sink, skewed key43 or blocking call.44- Exactly-once has a declared boundary. External effects outside the engine transaction/checkpoint45 need idempotency, fencing or their own transaction protocol.46- Checkpoint success is not automatically sink visibility. State when a two-phase sink commits and47 include that delay in the output-latency contract.48- State size does not determine Java heap by itself. Allocation, retained live state and object49 lifetimes affect GC; RocksDB caches/write buffers and file pages have distinct native/resident50 accounting. Managed memory is a budget, not an additional RSS category to sum twice.51- Backpressure is a symptom location, not necessarily the root. Walk downstream to the first52 operator whose output capacity degrades without an upstream cause.53- Busy task time is not CPU utilization: blocking callbacks and chained operators need stack,54 I/O and downstream evidence. Healthy throughput with stalled watermarks can instead be an55 event-time/idleness problem; do not add parallelism solely because a window emits nothing.56- Return the localized observation, competing cause, effective settings, bounded change and57 steady/recovery validation. Missing metrics or failed experiments remain inconclusive; measure58 successful visible results as well as input consumption, dropped events and retries.5960## References6162- [Kafka Streams operation](references/kafka-streams.md) — read for task/partition capacity,63 transactions, state stores, standby replicas or commit visibility.64- [Flink operation](references/flink.md) — read for operator backpressure, checkpoints, RocksDB,65 watermarks, savepoints or connector lifecycle.