Skip to content
$EngineeringAtlas

Backpressure, Explained With a Coffee Shop

Queues, load shedding, and what happens when producers outrun consumers.

Amit Kumar Singh2 min read

The Problem

Backpressure is what stops a fast producer from overwhelming a slower consumer. Without it, your API accepts more work than workers, databases, or downstream services can finish, and the system fails after the queue is already too large.

Why It Matters

Backpressure is the difference between a system that degrades and a system that collapses. A service under pressure should protect its most important work, reject work it cannot finish, and recover quickly when load drops.

This is common in real systems that use Kafka, RabbitMQ, SQS, Redis streams, HTTP APIs, and batch workers. The tool changes, but the core problem is the same: producers can often create work faster than consumers can complete it.

Project Example

An order service receives 2,000 checkout requests per second during a sale, but the payment provider can handle only 600 per second. If the API accepts all requests and blindly queues payment jobs, customers wait for stale jobs that will time out anyway.

Implementation Example

if (queue.oldestMessageAgeSeconds("payments") > 30) {
  return res.status(503).json({
    error: "checkout_temporarily_busy",
    retryAfterSeconds: 20,
  });
}

This is not just defensive coding. It is product behavior. A fast, honest failure lets the client retry later instead of waiting two minutes for a payment job that will no longer be useful.

Implementation Checklist

  • Put a hard max on queue depth or oldest-message age.
  • Return 429 or 503 when the system is saturated.
  • Use short request deadlines and pass them to downstream calls.
  • Separate high-priority work from background work.
  • Alert on queue age, not only queue size.
  • Add dead-letter queues for poison messages.
  • Stop retrying when the business deadline has passed.
  • Document which workloads can be dropped and which must be durable.

Production Notes

For user-facing APIs, the oldest message age is often a better alert than queue depth. A queue of 10,000 fast jobs may be fine. A queue of 100 jobs that are each 20 minutes old may be a customer incident.

In stream processing, backpressure should propagate upstream. If the consumer is slow because Postgres is overloaded, adding more consumers can make the database even slower.

Common Mistakes

  • Treating a queue as infinite capacity.
  • Scaling consumers without checking database and API limits.
  • Retrying everything immediately during an outage.
  • Measuring only average latency while p99 is burning users.
  • Hiding overload until every dependency is saturated.
  • Using one queue for urgent user work and slow background work.

Summary

Backpressure is a contract: the system says "not now" before accepting work it cannot complete. Real projects need bounded queues, deadlines, priority, and clear load-shedding behavior.

Amit Kumar Singh

// written by

Amit Kumar Singh

Software engineer writing about backend systems, cloud, and the realities of running code in production.

$ subscribe --weekly

The weekly engineering digest

Production-grade engineering writing in your inbox. No spam, unsubscribe anytime.

## related