Skip to content
Optimal Lab

System design · interactive

Backpressure

A producer sends 120 messages a second; the consumer can only handle 80. Something has to give: memory, messages, or the producer's speed.

Queue length, 20 s

Dashed: a bound of 200.

Queued
800
Wait
10.0 s
Dropped
0

producer now sending 120/s

The queue grows by 40 a second forever. After 20 s it holds 800 messages and each waits 10.0 s. Eventually memory runs out.

Queue

Step 1 of 4

  1. 1

    Unbounded queues hide the problem

    Everything looks fine while the queue grows. Latency climbs, then the process runs out of memory.

    A queue only absorbs bursts, not a sustained gap.

  2. 2

    Bound it and shed load

    Reject or drop when full. Fine for metrics or best-effort work; return 429 or 503 to callers.

    Drop oldest or newest depending on what's useful.

  3. 3

    Signal upstream to slow down

    Blocking writes, TCP windows, reactive-stream demand and pull-based consumers all tell the producer to wait.

    stream.write() returns false → wait for drain

  4. 4

    Then add capacity

    Backpressure buys time. If the gap is permanent, scale the consumer or reduce the work per message.

    Alert on queue age, not just length.

In production

Tools and technologies

Every queue and stream library has a backpressure mechanism.

Not tied to one language — use these names when you search docs or design a system.