Backpressure
Backpressure is a control mechanism that prevents fast producers from pushing more work into a system than slower consumers can finish. It turns overload into an explicit signal, such as waiting, refusing, dropping, or slowing input, instead of allowing queues, memory use, retries, and latency to grow until the service fails.
Backpressure is necessary because overload usually starts as a mismatch between arrival rate and completion rate, not as an instant crash. If incoming work keeps being accepted while workers are already saturated, the excess becomes queued work. Queueing increases latency, longer latency creates more concurrent in-flight requests, and higher concurrency adds still more delay. That is the same shape as latency increasing with base service time plus extra cost per concurrent request.
Mechanically, backpressure puts a limit somewhere work crosses a boundary. A server may bound its request queue, cap active workers, or reject when latency remains too high. A protocol may stop a sender when the receiver’s flow-control window is exhausted. A queue consumer may simply pull only as fast as it can process. Once the limit is reached, the producer must wait, retry later, receive 429 or 503, or have low-priority work discarded.
The trade-off is that backpressure makes failure visible to callers sooner. That is usually better than hiding overload in an unbounded buffer, but it means some requests are delayed, rejected, or dropped even while the machine may not look fully busy. Thresholds are workload-dependent: too strict wastes capacity, too loose recreates the queueing failure. Retries are especially dangerous unless they use backoff, because they can raise arrival rate without adding useful throughput.
Engineers meet backpressure in web servers, message queues, RPC frameworks, service meshes, and orchestration systems. Envoy circuit breakers limit pending requests and connections. Kubernetes readiness checks can remove an overloaded pod from new traffic. SQS with Lambda can cap concurrent consumers. HTTP/2 and gRPC use flow-control windows so receivers decide how much data can be sent. In all cases, the point is deliberate degradation rather than accidental collapse.
Common questions
- Is backpressure the same as rate limiting?
- They overlap, but they are not identical. Rate limiting usually enforces a policy at an edge, such as how much a client may send. Backpressure is feedback from a constrained consumer or downstream dependency. It may look like rate limiting when expressed as 429 or 503, but its purpose is to match accepted work to current processing capacity.
- Why not just make the queue bigger?
- A larger queue can absorb a short burst, but it also stores latency. If service rate stays below arrival rate, a bigger buffer only delays the point of failure while making each accepted request wait longer. Past a point, immediate rejection is kinder to callers and safer for the service than pretending the work will finish soon.
- Where should backpressure be applied?
- It depends on where overload is created and where it can be signalled safely. Good systems usually apply it at several boundaries: admission control at the front door, bounded queues inside services, concurrency limits around dependencies, and protocol-level flow control for streams. The earlier a system can refuse excess work, the less wasted work it creates.