What distinguishes a real graceful-degradation capability from an aspiration, and how do you design and validate a degradation ladder?
Show the full answer Hide the answer
The distinction
An aspiration is "the system degrades gracefully." A capability is a specific list of features, in order, each with a switch, an owner, a trigger and a rehearsal.
The test is simple: can someone turn off recommendations right now, in under a minute, without a deploy? If the answer requires a code change, a release, or a discussion, the capability does not exist — and it will not exist during the incident either.
Designing the ladder
Work from the critical user journey backwards. For a commerce system: browse → search → add to cart → checkout → pay. Everything not on that path is a candidate for degradation, in rough order of value:
- Personalisation and recommendations → fall back to popularity-based or cached results. Often the largest compute consumer and among the least essential.
- Reviews, ratings, social proof → serve stale or omit.
- Real-time inventory display → show cached counts with a disclaimer, and validate at checkout.
- Rich search → fall back to simpler keyword matching.
- Non-essential writes — analytics events, activity feeds, notifications → buffer or drop.
- Images at full resolution → serve smaller variants.
Everything above the line stays. The checkout and payment path is the last thing to degrade, and it should have its own reserved capacity so nothing else can consume it.
What each rung needs
- A switch that takes effect without deployment, and that does not require the control plane of the failing system. A kill switch that needs a healthy configuration service is not available during the incidents that matter — local caching with a long stale-serving window is the fix.
- A named owner who can authorise it, and a pre-agreed trigger condition so the decision is not a debate at 2am.
- A defined fallback behaviour, tested. "Recommendations off" must mean something specific — a popularity list, a cached response, an empty section that renders correctly — and the fallback path must itself be load tested, because it will be serving full traffic for the first time under the worst conditions.
- A user-facing message where the absence is noticeable, since communicated degradation is tolerated and silent degradation looks like a broken product.
Validating it
- Exercise each switch in production, on a schedule. A switch not thrown in six months does not work; the code beneath it has changed.
- Load test with the degradations active, establishing what the system can serve in degraded mode. This number is the actual answer to "how much traffic can we survive", and it is usually far higher than the normal-mode number, which is what makes the whole ladder worth building.
- Measure the capacity released by each rung, so the ladder is ordered by benefit rather than by intuition. Teams routinely find that the rung they assumed was most valuable frees almost nothing.
- Rehearse the decision, not only the mechanism — a game day where someone must choose which rung to pull from ambiguous signals.
The failure to avoid
Degradation that is discovered rather than designed. A system under stress will shed something; if nobody chose what, it sheds whatever fails first — which is frequently the checkout path, because it is the most complex and has the most dependencies. The ladder exists to make that choice in advance, in a room, with the business present.