1.What backpressure is and why it matters
Backpressure is any mechanism that stops a fast producer from writing work faster than a consumer can process it. Without one, the gap between the two rates has to live somewhere — usually an in-memory queue that grows until the process runs out of memory and crashes.
Key features
- A producer and a consumer rarely process at the same rate — a spike in traffic, a slow database write, or a consumer restart all widen the gap between write rate and drain rate
- Without backpressure, the gap is absorbed by an unbounded queue or buffer — memory usage grows linearly with how far behind the consumer falls, with no ceiling
- The failure mode is not gradual: memory grows quietly until the process hits its limit, then the process is killed (out-of-memory) or starts swapping, and every message still in the buffer is at risk of being lost
- Backpressure is a property of the whole pipeline, not a single component — a fix at the queue does nothing if the producer itself has no way to learn it should slow down
- The Reactive Streams specification (adopted into Java's Flow API and reactive libraries) treats backpressure as a first-class contract: a consumer explicitly signals how much it can accept, rather than a producer pushing blindly
The producer/consumer mismatch and its consequence without backpressure
- No backpressure
- Producer writes at full rate no matter what
- Queue grows without a ceiling during the spike
- Memory usage climbs until the process is killed
- Messages already buffered are lost on crash
- With backpressure
- Producer is signaled to slow down or blocked
- Queue depth stays within a known bound
- Memory usage stays flat and predictable
- Producer, not the queue, absorbs the slowdown
Command
# Unbounded: producer never checks consumer capacity
while True:
item = generate_work()
queue.put(item) # always succeeds, queue grows forever
# With backpressure: producer is forced to slow down
while True:
item = generate_work()
queue.put(item, block=True, timeout=None) # blocks once queue is fullBackpressure exists because a producer and consumer rarely process at the same rate, and the gap has to go somewhere. Without a bound on the queue, "somewhere" is process memory, and the failure looks like a sudden crash after a period of no visible warning.