Defining a degraded mode, deliberately
coreintermediateGraceful degradation is the practice of deciding, ahead of time and on purpose, exactly what a system can still do when a non-critical dependency fails, rather than discovering it by accident during an actual outage. This connects directly to the critical-vs-optional classification from Dependency Management: an optional dependency, by definition, is one whose failure should not stop the primary function — but "should not stop it" is not automatically true just because a dependency was labeled optional. It is only true if someone actually defined and built the specific reduced-functionality behavior for that failure case, tested it, and confirmed it produces a usable result rather than a confusing half-broken one. A degraded mode is that specific, defined behavior — not "the system tries to keep going and whatever happens, happens," but an explicit, designed answer to "if this dependency is down, this feature is disabled/reduced/replaced with a fallback, and here is exactly what the user sees instead." Systems that never do this work end up with an accidental, undefined degraded mode that emerges from whatever the code happens to do when a call fails — usually an error, a blank section, or a crash — none of which is the deliberate, still-useful reduced state that graceful degradation is aiming for.
Think of it as
A commercial airplane has a deliberately designed set of degraded modes for equipment failure — if one hydraulic system fails, there are backup systems and a defined reduced-capability flight profile, all specified in advance by engineers who asked "what can this plane still safely do with this system out" long before any specific flight. It is not the pilot improvising in the moment; the degraded behavior was designed, tested, and documented before it was ever needed. A system with no defined degraded mode is like a plane with no such engineering — when a system fails in flight, what happens next is whatever emerges from the wreckage of untested assumptions, not a deliberately chosen safe reduced state.
What we're doing: Compare what actually happens to a product page when the recommendations service fails, with and without a defined degraded mode.
- 3
- This line has no defined degraded mode — if recommendations_service raises, there is no code path that says what the page should do instead, so whatever the framework's default unhandled-exception behavior is (usually a 500 error page) becomes the accidental "degraded mode."
Why this works: Nothing about labeling recommendations-service "optional" in a dependency map changes what this code actually does when the call fails — the classification is a design intention, and without the corresponding code (and a test that actually exercises the failure), the intention and the real behavior of the system are two different things.
Classifying a dependency as optional without building its degraded mode
Wrong
Better
What you see: A design review or dependency map correctly lists recommendations-service as "optional, degrade gracefully," and a real outage six months later still takes the whole product page down, because the classification was never followed by the actual code change and test that would have made it true.
Why: A dependency map is a document describing intended behavior; it has no effect on the running system until the corresponding fallback code is written and verified — treating the classification itself as the fix is mistaking the plan for the implementation.
- Normal operation (start)
- → Dependency failure detected when timeout / error from optional dependency
- Dependency failure detected
- → Defined degraded mode active when pre-built fallback engages
- Defined degraded mode active
- → Dependency recovers when health check passes again
- Dependency recovers (end)
- → Normal operation when full functionality restored
Accidental vs. deliberate degraded mode for the same failure
Remember: A degraded mode is a specific, designed, and tested behavior for "this dependency is down" — not an emergent accident of unhandled errors. Classifying a dependency as optional is a necessary first step but changes nothing on its own; the fallback code has to actually be written, and then deliberately exercised (not just theoretically covered by a try/except) to confirm it produces a genuinely usable result.
See also: graceful degradation examples · mapping critical vs optional dependencies · preventing cascading failures via decoupling · health checks and synthetic monitoring

