Events and messaging

Updated 5 min read

Backpressure: When Your System Must Say Not Yet

Photo uploads succeed while property listings wait indefinitely. Slow the source, account for accepted work and clear the backlog without recreating overload.

A property agency uploads photos. The service accepts the files quickly, queues image-processing tasks and reports success. During a bulk upload, the backlog grows while new listings remain without pictures. Technically the service is available. For the people trying to publish listings, work has stopped.

The buffer absorbed incoming work; it did not create processing capacity. If arrivals consistently exceed completions, a larger queue merely postpones unacceptable delay. The system needs feedback: the receiver is falling behind, so the source must reduce its output.

What backpressure actually means

Strictly, backpressure communicates a receiver's capacity constraint upstream. A consumer indicates how much work it can accept or causes the producer to pause until capacity is available. A worker might request another batch only after freeing its resources. This demand-based approach is central to Reactive Streams.

Related protections include rate limits, admission control and load shedding. They can protect a service without necessarily creating that feedback loop. Returning “busy” to a client that immediately tries again has not made the source slow down.

Follow the signal all the way upstream. The worker slows, stops taking jobs and the queue reaches a threshold: what changes at the uploader? If it keeps accepting files without a limit, pressure has simply moved into storage. Intermediate buffers need boundaries too.

Estimate waiting, not just storage space

Take a deliberately simplified example with equal-cost jobs. Workers finish 100 jobs a second while 80 new jobs arrive. Only 20 jobs a second of spare capacity remain to clear a backlog of 6,000. At unchanged rates, that takes about five minutes, not one. If incoming work equals processing capacity, the old backlog does not shrink.

Actual photos have different sizes, formats and processing requirements. Queue length therefore cannot be turned directly into a promised completion time. Measure completion throughput, outstanding age, in-flight work and the workload's cost distribution.

Depth and age are both useful, but neither tells the whole story. A few permanently failing jobs may remain old while the main flow is healthy. A large fresh queue may represent a short burst that will clear quickly. Waiting-time distributions and completion against the customer deadline provide a better picture.

Include work already fetched by workers. It may disappear from the ready queue while still occupying memory and waiting on another system. A controller watching only that queue can reopen intake too soon. Outstanding-work limits must account for these in-flight jobs as well.

Accepting a file creates an obligation

Before acceptance, the service can decline more work clearly while preserving the user's draft. After acceptance, it needs durable original storage, a recorded processing obligation and a way for the customer to learn the outcome. A queue limit is not permission to silently forget work already acknowledged.

Keep “not accepted”, “accepted and waiting”, “processing”, “ready” and “needs attention” distinct. A retry using the same operation identity should not enqueue another copy. Otherwise customers trying to accelerate publication make the backlog worse.

Cancellation depends on meaning. An old thumbnail task may be superseded if the source image is safe, a new version makes the old work unnecessary and the product explicitly allows replacement. The same rule cannot erase the only record of an accepted obligation. Distinguish replaceable computation from work that must reach an accounted-for outcome.

One archive import should not occupy everybody's day

A single first-in-first-out queue is simple until a large agency submits its entire archive before everybody else's everyday work. Per-organisation limits on outstanding jobs, separate interactive and bulk queues, or allocated shares of processing capacity can help.

Giving new listings permanent priority can also starve the archive import indefinitely. Background work needs some guaranteed progress, not merely a polite name for lowest priority. Capacity allocation should reflect the service the company has promised each customer.

This is different from adding workers without limit. If they already saturate shared storage, more workers increase the pressure. The Azure queue-based load-leveling guidance discusses aggregate processing limits and downstream constraints.

Resuming the flow is part of the design

When the queue drops just below a threshold, releasing every waiting producer at once can recreate overload. The system oscillates between full traffic and full stop. Separate slowdown and recovery conditions, followed by a gradual increase in intake, can avoid that pattern.

Waiting also needs a limit at the source. A producer that cannot pause or store its work may lose data or fail when the feedback arrives. The product then needs a different agreement: bounded acceptance, durable deferred storage or explicitly permitted dropping. Identify that consequence before a buffer fills.

Retries count as traffic too. If every rejection immediately causes another attempt, even refusing work can consume the service's capacity. Google SRE's overload guidance covers cooperation between clients and backends. Bounded retries with backoff help only when they respect the overall deadline and are safe for the operation.

Keep testing until the backlog is accounted for

Slow the image processor in a controlled test while ordinary uploads continue. Check memory and queue bounds, the producer's reaction, preservation of accepted work and the ability of other customers to publish listings. Restore capacity and follow the deferred work through to an outcome.

The result should include more than CPU charts. Each accepted test task should be completed, explicitly cancelled under the agreed rules or assigned for investigation. Measure how long normal waiting times take to return. A system that survives the peak but spends tomorrow processing yesterday's work has not yet recovered in the way the business needs.