← Flink

Debugging Flink Backpressure and Checkpoints: Locate the Slow Stage First

Use a source-to-sink pipeline to distinguish downstream bottlenecks, data skew, state I/O, and barrier-alignment delays.

Read in Chinese →

Engineering notes with synthetic examples. Version scope and references are included in each article.

When Kafka backlog rises and checkpoints time out, increasing parallelism is rarely the most informative first step. If a downstream service is throttling requests, more concurrency may amplify failures and retries. Separate “where is it slow?” from “why is it slow?” before choosing a setting to change.

This article uses Flink 1.15 and the illustrative pipeline Source → Parse → Enrich → Keyed Process → Sink. Any performance numbers are hypothetical examples.

The backpressured task is not necessarily the bottleneck

Records move downstream; backpressure propagates upstream. A backpressured Source often means downstream capacity is restricting its output, not that the Source itself is too slow. Flink’s Web UI exposes busy, idle, and backpressure time metrics for inspecting parallel task instances. Flink 1.15: Monitoring Back Pressure

Work upstream from the downstream end to locate the blocking boundary, and inspect individual subtasks. If fifteen Process instances are relatively idle while one stays busy, examine key distribution first. If all are busy with high CPU use, inspect computation and serialization. If CPU is low but request latency is high, investigate external waits and connection pools.

Operator chaining can place several functions in one task, so one graph node does not necessarily equal one business stage. If needed, break the chain in a controlled environment or add per-stage timing. Otherwise reflection-based parsing, network calls, and business computation may all disappear into a single busy metric.

Preserve evidence before running a controlled experiment

A useful snapshot includes input rate and backlog trends, per-subtask input and output volumes, CPU and GC behavior, external-request latency and errors, state size, and checkpoint-stage durations. Record when the issue began and the most recent release, traffic change, or dependency change.

Suppose the dimension service used by Enrich suddenly has higher tail latency. Test whether reducing external calls relieves backpressure: in an isolated environment, substitute a fixed response or controlled cache while keeping input unchanged. If the problem improves, investigate timeouts, concurrency limits, cache hit rates, and retries. An unbounded production queue does not solve a slow dependency; it converts delay into a memory risk.

For skew, measure load by key or business partition. Salting may spread a hot key, but can change aggregation, deduplication, and ordering semantics. It needs a subsequent merge or a deliberate hot-key strategy, not a random suffix added indiscriminately to every key.

Break checkpoint duration into stages

A slow checkpoint can result from delayed barrier arrival, alignment across inputs, blocking synchronous snapshot work, or slow asynchronous upload. Combine subtask-level metrics rather than relying on one end-to-end duration.

ObservationHypothesis to investigate first
Start delay and alignment rise with backlogBackpressure is delaying barrier propagation
Synchronous duration suddenly increasesMore expensive state serialization or synchronous work
Asynchronous duration and storage latency increaseCheckpoint-storage I/O bottleneck
A few subtasks hold much larger stateKey skew, excessive retention, or ineffective cleanup

These are investigative starting points, not proof of causation. A jump in state size may come from higher traffic or from a deduplication-key change that increases cardinality. Compare state trends with unique-key counts, TTL settings, and release history.

Which problem do unaligned checkpoints address?

Under severe backpressure, unaligned checkpoints include some in-flight data in the snapshot so barriers need not wait for all buffered records to be processed. This adds storage I/O. If snapshot-upload bandwidth is already the bottleneck, it may not help. Flink 1.15: Checkpointing under backpressure

Flink 1.15 also imposes configuration constraints, including exactly-once checkpoints and a single concurrent checkpoint. Flink 1.15: Checkpointing

I would evaluate this as a conditional experiment under the same input load. Compare checkpoint success rate, size, end-to-end latency, and actual recovery time after a failure. Declaring success solely because checkpoints stop timing out can overlook the volume of in-flight data that recovery must read.

What counts as a completed fix?

After a change, observe at least a traffic peak and one recovery exercise. Confirm that backlog drains rather than merely stops growing. Successful downstream writes must keep pace, and the volume of quarantined errors must not quietly increase.

If scaling is the final choice, state whether it addresses CPU, state capacity, or throughput. Check whether source partitions, hot keys, or external rate limits constrain the benefit. A useful incident conclusion is concrete: “Dependency tail latency increased waiting; after bounding retries and improving cache hits, backlog began to drain under controlled load.” “Tuning made a big difference” is not enough.

Keep the configurations and observation windows from before and after the change. A temporary traffic drop can make an ineffective change appear successful, so compare similar input volumes and event distributions. Average latency can hide the tail; also inspect high-percentile latency and the age of the oldest queued event.

References

← More topicsBack to top ↑