Systems
Backpressure Keeps Busy Services Alive
How bounded concurrency, queues, deadlines, and load shedding prevent a traffic spike from turning into a cascading outage.
A service rarely fails because one request is too difficult. It fails when accepted work grows faster than the service can finish it. Backpressure gives the system a controlled way to say “not yet” before memory and latency collapse.
This guide focuses on the decisions that survive contact with production: clear boundaries, observable behavior, and a feedback loop that reveals when an assumption is wrong.
The problem worth solving
Unbounded Promise.all calls, connection pools, and queues hide overload until every request becomes slow. The slowdown causes retries, retries add more load, and the failure spreads to dependencies.
The useful move is to make the hidden constraint explicit. Write down what must stay correct, what can be delayed, and how the system should behave when a dependency fails. That turns a vague idea into something a team can test.
A practical implementation
Set a concurrency budget from measured capacity. Queue only a bounded amount of work, attach deadlines, and reject excess requests with a response clients can handle. Track saturation as carefully as errors.
import pLimit from 'p-limit'
const run = pLimit(20)
export async function fetchProfiles(ids: string[]) {
return Promise.all(ids.map((id) => run(() => fetchProfile(id))))
}
The example is intentionally small. In a real project, add structured logs, metrics around the failure path, and tests for retries or partial results. Keep the interface narrow so the implementation can change without forcing every caller to change too.
What to measure
Measure the outcome rather than activity. For software, that may be latency, error rate, queue depth, or recovery time. For product work, it may be activation, retention, or the number of useful conversations. Review the signal on a regular cadence and record what changed.
Takeaway
Capacity is a product constraint. Bound the work, expose saturation, and fail quickly enough for the rest of the system to recover.
Start with the smallest version that can teach you something, make its behavior visible, and improve it from evidence. That rhythm is more dependable than trying to design the final answer in one pass.
Further reading
Explore more Systems articles from this journal.
Tushar Sharma