# Backpressure

> Let a slow consumer slow the producer down instead of drowning in a growing queue.

Concept · Async work & messaging · https://levelcode.org/concepts/backpressure

Backpressure is any mechanism by which a component that can't keep up signals upstream to send less. Without it, the excess piles up somewhere — usually in an unbounded queue or buffer — until memory runs out or every item waits so long that it's useless.

## Why unbounded queues fail

By [Little's law](https://levelcode.org/concepts/littles-law), wait time = queue length / processing rate. If producers send 1,200 messages per second and consumers handle 1,000, the queue grows by 200 per second; after ten minutes, a new message waits two minutes. For a request–response system, that means every request times out — the server is busy, but doing work nobody will receive.

## Forms of backpressure

- **Bounded queues** that block or reject when full. In Go, a buffered channel blocks the sender when it's full: that *is* backpressure.
- **Explicit rejection**: return `429` or `503` with `Retry-After` so callers slow down ([load shedding](https://levelcode.org/concepts/load-shedding)).
- **Flow control** in protocols: TCP's receive window, HTTP/2 stream windows and gRPC streaming all stop the sender when the receiver's buffer fills.
- **Pull-based consumption**: consumers fetch when ready (Kafka consumers, reactive streams with demand signals), so a slow consumer simply falls behind rather than being overwhelmed.

## In asynchronous pipelines

With a durable log, falling behind is safe for a while — the backlog is stored — but you must notice it:

- Monitor **consumer lag** (messages or seconds behind the head) and alert when it grows.
- Scale consumers with lag, up to the partition count.
- Decide what happens if lag exceeds retention: messages are deleted unread.

## The principle

Every queue should have a bound and a policy for what happens at the bound: block, reject, drop the oldest, or drop the newest. Choosing that policy deliberately is the difference between graceful overload and collapse.
