Pattern · seen in 7 breakdowns across 7 companies

Priority-Aware Load Shedding

When a system is overloaded and has to turn work away, drop the least important requests first, so the critical ones keep flowing instead of failing along with everything else.

The mechanism

The pattern on its own, with the specifics of any real system stripped away: just plain traffic, one capacity limit, and a single toggle that turns priority shedding on or off.

LIVE ARTIFACTTHE PATTERN, GENERALOPEN FULL SCREEN ↗
THE IDEATwo classes of traffic flow toward a server that can serve 50 requests a second: gold payments and gray batch jobs. Priority-aware shedding decides in advance what matters least and drops it first.
WHAT TO TRYDrag TRAFFIC past 50 req/s. With SHED SMART on, payments hold at 100% while batch jobs absorb the loss; flip it off and payments fail with everything else.

Drag TRAFFIC past capacity, then flip SHED SMART - the toggle is the pattern.

Definition

Priority-aware load shedding means dropping the least important traffic first when a system is overloaded, instead of dropping requests evenly. Every request carries a priority tag - a small tier number, often t0 through t5. As the system gets overloaded, it drops the lowest-tier requests first. It only moves up to higher tiers if the overload continues after the lower tiers are already gone.

SHED FROM THE BOTTOM UP
Three panels of priority tiers t0 to t5; as load rises, dropped tiers grow from the bottom up
Requests are tagged into priority tiers, t0 (most critical) down to t5. As load climbs past capacity, the system drops from the bottom up - t5 first, higher tiers only if pressure keeps rising.

The idea is simple: not all traffic is equally worth keeping. A storage system might serve both ride-pricing queries (where every dropped request hurts a real user) and batch analytics jobs (where a dropped request only delays processing). Those two should not be dropped at the same rate. Without priorities, the system protects itself by dropping requests evenly: it stays up, but it throws away important and unimportant work at the same rate, so it survives while still failing at what matters most.

The pattern needs three things to work:

  1. Accurate priority tags on every request, applied the same way across the whole system.
  2. A shedding mechanism that drops by tier, instead of rejecting requests at random.
  3. The discipline to keep those tags honest as the system grows.

That third one is the hardest to keep up. Once people see their own jobs getting dropped first, it is tempting to relabel them as 'user-facing' - and if nobody checks, the priorities slowly stop meaning anything.

The pattern is most valuable in mixed systems, where important traffic and lower-priority traffic (work that can wait or be retried) share the same infrastructure. It is less useful in two cases:

  1. When all traffic matters equally, so plain, even shedding already does the right thing.
  2. When each class already has its own reserved capacity, so that separation enforces priority and nothing needs to be shed by tier.

When it applies

01Important and low-priority work share one overloaded path: user-facing requests and background or batch jobs run through the same infrastructure, and only some of it is worth protecting when capacity runs short.
02Some users pay for premium service and others are on a free tier: priority tags turn that promise into something the system can actually keep under overload, by shedding free-tier traffic before paid traffic.
03Query importance varies widely inside one storage system: dropping any number of analytics queries is better than dropping a single payment query, so the store sheds by importance instead of evenly.
04Shedding buys time while new capacity comes online: as machines spin up, dropping low-priority traffic first keeps the user-facing service healthy until they are ready.
05The team has already accepted that some requests will be dropped under overload: the real question is which ones, not whether to drop any at all, and this pattern makes that choice deliberate.

Tradeoffs

The whole thing depends on honest priority tags: if low-priority work gets labeled 'user-facing' just because a team wants it protected, the protection quietly stops working. Keeping the tags honest is ongoing work, not a one-time fix.
Low-priority work must expect to be dropped, sometimes a lot: anything running at a low tier needs to retry or otherwise cope when its requests are dropped, or it will fail in confusing ways. A batch job with no retry logic will just lose the work that gets dropped.
Tiers tempt people to cheat: once teams see their work dropped first, some will label it higher than it really is to jump the queue. Someone has to keep watching and correcting the labels, or the priorities slowly stop meaning anything.
Adding a tier later is harder than it looks: you have to re-sort all the existing traffic against the new tier, and other systems that lean on the current tiers - alerting, reporting, capacity planning - usually have to change too. It is worth planning the tiers carefully up front.

The same move, 7 ways

Every row is a production system that bet on this pattern — the note says how, in that system's own terms.

Uber
Uber Engineering
2026
Every request carries a priority tier, and when the system has to drop load it starts from the lowest tier and works up, so batch and analytics traffic absorbs the cost while rides and payments are protected. Cinnamon's t0-t5 tiers are a full worked example. The catch is that this only works if the tiers are honest: the pattern's whole value rests on every team classifying its traffic correctly, which is an editorial discipline across the organization, not just an engineering one. Read the breakdown →
Netflix
Netflix Technology Blog
2024
When a service has to drop load, it drops the least important traffic first instead of throttling everything equally. Netflix does this at two grains: four priority buckets (CRITICAL, DEGRADED, BEST_EFFORT, BULK, borrowed from Linux's traffic-priority levels) shed from the bottom up, and inside PlayAPI a two-partition limiter guarantees user-initiated playback its full share while pre-fetch gets only leftover capacity. Uber solves the same problem in its storage layer with t0-t5 tiers; Netflix solves it in the service layer with request buckets. The same shed-the-lowest-value-first idea working at different layers of two different stacks is what makes it a general pattern rather than one company's trick. Read the breakdown →
DoorDash
DoorDash Engineering Blog
2023
Third company. Uber tiers the drop budget, Netflix shields playback; DoorDash's adaptive concurrency limiter reads request priority from headers and admits high-priority traffic first under overload. Lighter-weight instance than either: priority here is a property of the shedding interceptor, not a platform-wide taxonomy. Read the breakdown →
LinkedIn
LinkedIn Engineering
2023
LinkedIn's version is the fleet-wide default: three priorities - optional, degradable, non-degradable - set at the data-centre edge and carried through the whole chain of calls. Inside each priority, users are sorted into groups by a hash of their ID, so escalation drops whole groups at a time: the same few degrade consistently rather than everyone at random. The distinctive detail is that adding priority broke the load metric, forcing a move from capping requests in flight to capping request rate, tracked as a live breakdown per service and per priority. Read the breakdown →
Slack
Slack Engineering
2022
Recurs in the storm rather than in the design phase: the client-boot throttle was an explicit priority call — users without booted clients sacrificed so connected users kept working and the refill queries could land — followed by the return-trip discipline the class demands: one too-large limit increase caused a relapse; small increments with goodput watched at each step restored full service. (Conditional slug per the round-24 protocol: agent aligns to the live pattern name.) Read the breakdown →
Amazon (AWS)
Amazon Builders' Library
2019
When a server has to drop load, it shouldn't drop at random: it should rank requests and drop the least important first. The rankings here are all about not wasting work: the load balancer's health check above everything (drop it and the whole fleet shrinks), requests that finish work above ones that start it, later pages of a result above the first, normal traffic above bursts, shiftable crawlers below real users. And the ranking belongs at the front of the system, because if different layers deep in the stack disagree about what's important, they waste the very work they're trying to save. Uber, Netflix, and Stripe each built a mechanism for this; this article writes down the rules they all follow. Read the breakdown →
Stripe
Stripe Engineering
2017
When a system has to drop load, it decides in advance which traffic matters most and drops the least important first, rather than dropping whatever happens to be in the queue. Stripe's version is the most legible example on the site: a fixed slice of the fleet is permanently reserved for critical methods, and a four-tier ladder (test mode, then GETs, then POSTs, then critical) sheds from the bottom up. The reserved-capacity idea is what makes it distinctive: priority is enforced by setting aside capacity ahead of time, not only by choosing a drop order once the pressure hits. Uber, Netflix, and DoorDash each solve the same problem differently, with tiers and controllers, playback protection, and priority headers respectively; Stripe's is the plainest to read and, from 2017, the earliest. Read the breakdown →

Often used together

Patterns sharing breakdowns with this one — derived from co-occurrence, threshold ≥2 shared.

Problems this pattern answers

The walls where its breakdowns live — each opens the cross-company comparison.