My event-driven server stayed responsive under load, but its memory use climbed steadily. I had removed blocking and accidentally built an extremely efficient machine for accepting work it could not finish.

Each connection had an output buffer. Producers appended responses faster than the network drained them, so those buffers became an unbounded queue distributed across clients. Nothing was technically stuck. The server was merely saving enough unfinished work to become stuck later.

Backpressure means carrying limited downstream capacity toward the producer. When a connection’s output crosses a high-water mark, I stop reading more requests from it or stop scheduling new work. Once buffered output falls below a lower mark, reading resumes. Separate thresholds avoid switching state on every small write.

The same rule applies between the event loop and worker pool. A bounded job queue makes overload visible. If it is full, the loop must defer input, reject work or shed a connection according to policy. Adding another unbounded queue does not increase capacity; it increases the delay before admitting there is none.

I prefer bounded queues and explicit overload behavior, even when rejection feels impolite. The exact limits require measurement, and short bursts deserve some room. But a service that says “not now” can recover. One that accepts everything may respond to nobody, which is very accommodating in principle and less so in practice.