# Backpressure

> Backpressure is feedback that makes a producer slow down when a downstream consumer cannot keep up. In system design, it prevents temporary overload from turning into unbounded queues, exhausted memory, and cascading failures.

Source: https://sysround.com/concepts/backpressure
Updated: 2026-11-05


## How backpressure works

Start with a producer, a buffer, and a consumer. If producers send 10,000 events per second but consumers process only 8,000, the buffer grows by 2,000 events per second. A queue absorbs a burst; it does not fix a sustained capacity deficit.

Bound the resources between stages: queued bytes, queued items, in-flight requests, and concurrent tasks. Choose limits from memory budgets and acceptable waiting time, not arbitrary queue sizes. Bound individual message sizes too.

Send capacity feedback upstream. A consumer can grant credits for a limited number of messages, a worker can stop fetching when its in-flight limit is reached, or a bounded channel can make the producer wait. Resume production when capacity becomes available, often using separate pause and resume thresholds to avoid rapid toggling.

Propagate the signal across boundaries. If a worker pauses reads from a broker, the broker backlog still grows unless ingestion also slows or storage absorbs it within a defined retention budget. HTTP services can reject new work with an appropriate overload response; cooperative clients must then reduce their sending rate and retry with backoff and jitter.

Define what happens when waiting is no longer acceptable. Durable jobs may remain queued within storage and deadline limits; replaceable state updates may be coalesced; slow live clients may be disconnected and required to resynchronize. Dropping or rejecting work is load shedding, which often complements backpressure but is not the same mechanism.

## Worked example: A notification provider slows down

Suppose an email pipeline accepts 5,000 messages per second, but its provider can currently handle only 3,000. The durable backlog grows by 2,000 messages per second, so 120,000 messages of free queue capacity buys only 60 seconds. Workers cap concurrent provider requests and stop fetching when their in-flight budget is full. That protects worker memory but does not protect broker storage. At a backlog-age threshold below the delivery deadline, ingestion reduces admission for bulk campaigns while transactional messages use a separate capacity budget. Deferred producers retry with backoff and jitter. Once capacity recovers, admission rises gradually so new traffic plus backlog draining stays within provider limits. Already accepted messages remain durable rather than being silently dropped.

## Trade-offs

- **Bounded memory versus producer delay.** Making producers wait protects consumers but increases upstream latency and may cause requests to exceed their deadlines.
- **Burst absorption versus stale work.** Larger queues absorb longer bursts but consume resources and let work wait long enough to become useless.
- **Durability versus storage limits.** A durable queue survives process failures, but sustained overload still requires an explicit storage, retention, and admission policy.
- **Throughput versus control responsiveness.** Large batches and generous in-flight windows improve utilization but allow more work to accumulate before feedback takes effect.
- **Global protection versus fairness.** A shared capacity limit can let one noisy tenant or slow destination stall unrelated traffic unless queues and budgets are isolated.
- **Lossless delivery versus freshness.** Preserving every event may increase lag, while coalescing or dropping updates is safe only when the product's delivery semantics allow it.

## When to use it in a system design interview

- An asynchronous pipeline has stages with different or variable processing rates, such as ingestion, indexing, or media processing.
- A service depends on a slow database or external provider and needs to bound outstanding requests.
- A streaming service must handle slow clients without building an unlimited per-connection backlog.
- Bursts, retries, or outage recovery can produce work faster than workers can drain it.
- Several tenants or workloads share resources, and one overloaded path must not stall everyone else.

## How to bring it up in the interview

- Identify the bottleneck and quantify the mismatch: arrival rate, processing rate, backlog growth, and time until a buffer fills. Interviewers often ask whether the system can ever catch up.
- Name the exact control mechanism and boundary: bounded worker concurrency, consumer credits, paused broker fetches, or producer admission. Explain where the backlog moves when that boundary stops accepting work.
- State the overload contract explicitly: wait, reject, persist, coalesce, or disconnect. Expect follow-up questions about which data may be lost and what an acknowledgment guarantees.
- Describe recovery as well as overload: gradually resume traffic, cap retries, and avoid releasing a backlog faster than the dependency can handle.
- Track oldest queued-item age, queue bytes, in-flight work, processing rate, rejection rate, and end-to-end latency. Explain how per-tenant or per-destination limits prevent head-of-line blocking.

## Common mistakes

- Calling an unbounded queue a backpressure mechanism; it only postpones resource exhaustion.
- Pausing a consumer without accounting for backlog growth, retention limits, or disk exhaustion at the broker.
- Blocking request threads indefinitely instead of using bounded waits, cancellation, and explicit overload responses.
- Assuming autoscaling removes the need for backpressure, even when scaling is delayed or the bottleneck is a fixed-capacity dependency.
- Treating every stream as disposable: coalescing stock-price snapshots may be acceptable, but silently dropping orders or document edits is not.

## Interview questions where it comes up

- [Design a notification system](https://sysround.com/questions/design-notification-system): Slow providers require bounded worker concurrency, controlled retries, and separate capacity budgets for competing notification traffic.
- [Design a metrics monitoring system like Datadog](https://sysround.com/questions/design-metrics-monitoring-system): Ingestion bursts and outage recovery require bounded buffering and explicit policies for slowing senders or dropping samples.
- [Design a distributed message log like Kafka](https://sysround.com/questions/design-kafka): Slow readers expose the limits of retention and shared disk bandwidth, requiring explicit producer and consumer resource controls.
- [Design a distributed message queue like RabbitMQ](https://sysround.com/questions/design-message-queue): Prefetch limits, bounded in-flight deliveries, and producer admission keep hot queues and retry storms from exhausting resources.
- [Design a real-time stock price feed](https://sysround.com/questions/design-stock-price-feed): Hot-symbol fanout needs bounded per-client delivery and conflation so slow viewers do not accumulate obsolete prices.
- [Design Facebook live comments](https://sysround.com/questions/design-live-comments): Large live audiences require bounded outbound queues and a reconnect policy for viewers who cannot keep up.
- [Design a distributed tracing system](https://sysround.com/questions/design-distributed-tracing): Bounded exporter buffers and controlled ingestion prevent a slow tracing backend from blocking application requests.
- [Design a system to run commands across a fleet](https://sysround.com/questions/design-fleet-command-system): Fleet-wide dispatch needs bounded fanout and agent execution limits to avoid overwhelming machines and shared dependencies.

## FAQ

### What is the difference between backpressure and rate limiting?

Rate limiting enforces an allowed request rate, often based on a policy or quota. Backpressure responds to downstream capacity and asks upstream stages to slow down. A dynamically adjusted rate limiter can be one way to implement backpressure.

### Does a message queue provide backpressure automatically?

Not by itself: a queue buffers the difference between production and consumption. Consumer prefetch limits can bound in-flight deliveries, but producers may still fill broker storage. End-to-end protection requires bounded storage and a policy for slowing or rejecting producers before those bounds are exhausted.

### How do you handle backpressure with WebSockets?

Keep a bounded outbound buffer for each connection and monitor queued bytes and update age. For replaceable state, coalesce updates; for durable events, stop live delivery or disconnect slow clients and let them resume from a cursor. Transport flow control alone does not bound application-level queues.

## Related concepts

- [Message queues](https://sysround.com/concepts/message-queues)
- [Load shedding](https://sysround.com/concepts/load-shedding)
- [Retries, backoff and jitter](https://sysround.com/concepts/retries-backoff)
- [Bulkheads](https://sysround.com/concepts/bulkheads)


---
SysRound (https://sysround.com) is an AI practice tool for system design interviews: a voice or typed AI interviewer, a shared whiteboard, then feedback on every skill and a model answer. Its feedback is AI-generated and can be wrong.
