Fallback Independence
The requirement that a degraded path fail independently of the primary - and be exercised continuously, because fallbacks that are never run do not work.
A fallback exists to serve requests when the primary path cannot. It only does so if two conditions hold, and both are frequently violated:
1. It does not share a failure cause with the primary. A fallback that calls the same feature store, the same database, the same identity service, or runs on the same saturated cluster is not a fallback. It is a second copy of the failure.
2. It works. Which means it must be run continuously, not held in reserve. Code paths that are never executed rot: a dependency changes, a schema moves, a configuration expires, and nothing notices because nothing runs it.
Why it matters
Graceful degradation is one of the highest-value reliability properties available — it converts a hard dependency into a soft one and removes a term from the availability product. But an untested, non-independent fallback provides the appearance of that benefit while delivering none of it, which is worse than having no fallback, because the architecture's availability was calculated as though it worked.
Implementation patterns
- Serve a small percentage of traffic from the fallback continuously. This is the single most important practice: it proves the path works, measures its quality, and makes its degradation visible as a metric rather than as a surprise.
- A dependency audit per fallback. List everything the fallback touches and check it against the primary's dependency list. Any overlap is a shared failure cause.
- Prefer statically-generated fallbacks for the deepest rung — a precomputed list, a cached artefact, a hard-coded default — because anything with zero runtime dependencies cannot fail with the primary.
- A ladder rather than a binary. Cached personalised result, then a cheap always-available model, then a coarse popularity ranking, then a static default. Different users have different amounts of usable fallback data.
- Distinct telemetry per rung, so the business impact of degradation is measurable and the system's state during an incident is legible.
- Fault injection in production, continuously, so regressions are caught by the system rather than by customers.
Industry example
When a recommendation service fails on a discovery-driven platform, the tempting fallback — "serve results from the previous model" — usually fails, because the older model shares the serving infrastructure and the feature store with the current one and is therefore unavailable for the same reason.
The ladder that works starts with cached per-user recommendations, which are slightly stale and nearly indistinguishable from fresh for most users; falls through to a cheap model using only signals already present in the request, with no feature-store lookup; then to popularity or trending content segmented by whatever coarse context is available; and finally to a static curated set requiring no dependency at all.
Each rung has fewer dependencies than the one above it, which is the design principle: descending the ladder must monotonically reduce the number of things that can fail.
The same structure appears in commerce degradation ladders, where the deepest rungs are deliberately static because a static artefact cannot be affected by whatever is happening upstream.
Failure scenarios
- The fallback shares a dependency, so it is unavailable exactly when needed.
- The fallback is never exercised, and fails on first use under maximum pressure.
- Degradation is silent, so nobody knows the product has been serving a degraded experience for hours.
- The fallback is slower than the primary, so degrading makes latency worse rather than better.
- Infinite spinner as the de facto fallback, which converts a degraded experience into a broken one.
Trade-offs
Maintaining an independent fallback means building and operating a second path, keeping it warm, and accepting the cost of serving some traffic from a lower-quality answer permanently. For genuinely optional features that cost is easy to justify; for the deepest rungs it means keeping a static artefact fresh enough to be useful.
The alternative — no fallback, or an untested one — means the dependency is hard, and every availability calculation must include it as a multiplied term.
Interview question
"Your personalisation service is down during peak. Give me the fallback ladder, and for each rung tell me what it depends on and when you last ran it."