Backpressure in Practice
also called Flow Control, Push-Back
Signalling upstream to slow down so queues stay bounded, and what to do at boundaries where the producer cannot be slowed.
Definition
A mechanism by which a slow consumer causes its producer to reduce its rate, so that queues between them remain bounded rather than growing until memory is exhausted.
Why it matters
A pipeline is only as fast as its slowest stage. Without feedback, faster stages keep producing into buffers that grow until the process is killed — and the failure appears as an out-of-memory kill in a component that was working correctly.
Bounded queues with backpressure convert that into a graceful slowdown, which is a far better failure mode: the system degrades in a way that is visible, measurable and recoverable.
Implementation patterns
Pull-based consumption. A consumer reading from a durable log at its own rate gets backpressure for free — falling behind manifests as lag rather than as memory pressure. This is one of the underappreciated architectural advantages of putting a log between stages rather than connecting processors directly.
Bounded queues that block or reject on write, rather than unbounded ones that accept everything.
Protocol-level flow control — TCP windows, HTTP/2 stream windows, gRPC flow control — where the transport itself propagates the signal.
Reactive streams, where the consumer requests n items and the producer sends no more than that.
Explicit rejection — returning 429 or 503 — which is backpressure expressed to a caller you do not control.
Failure scenarios
Unbounded buffers, which trade a fast visible failure for a slow invisible one ending in an out-of-memory kill.
Backpressure treated as a healthy steady state. A job running under sustained backpressure is not healthy; it is failing to keep up, and lag is growing somewhere upstream. It is a symptom to diagnose, not a mechanism to rely on.
Producers that cannot be slowed. A device fleet, a payment network, a partner feed — the signal has nowhere to go, and rejecting simply produces retries that amplify the load.
Backpressure propagating into a user-facing path as unbounded latency rather than as a fast rejection, so users wait rather than being told to try again.
Industry example
The IoT ingest boundary is where this gets interesting, because devices will keep transmitting whatever you do. The techniques that work there are all forms of reducing the demand rather than signalling it: filter at the edge by reporting on change rather than on a timer; aggregate at the gateway to send a minute's statistics rather than sixty readings; shed by priority so alarms survive and routine telemetry does not; and buffer locally so a loss becomes a delay.
Trade-offs
Backpressure preserves correctness and stability at the cost of latency and, ultimately, of rejecting work. The alternative — accepting everything — preserves throughput until it collapses entirely.
Where the producer cannot be slowed, the choice is not whether to shed but what to shed, and that is a business decision that must be made in advance rather than discovered when the buffer fills.
Interview question
An IoT ingestion pipeline is falling behind. The devices cannot be slowed down. What are your options?
Look for recognition that standard backpressure does not apply, followed by a ranked set: buffer at the edge, aggregate at the gateway, filter at source, shed by priority, sample, spill to cheap storage. The strongest answers insist the degradation policy be decided in advance and note the exception — anomalies and alarms need full resolution and must survive every filter.