Graceful degradation
Total failure is rarely necessary. Most products have a core that can keep working while peripheral features are unavailable, and the design question is which parts are essential and what the others do when their dependency is gone.
Method
- Classify features by criticality. What must work, what should work, and what can disappear without the product being unusable.
- Isolate the non-critical. A recommendation service failure must not block checkout, which requires the dependency to be optional in code rather than in intention (see bulkheads).
- Define the degraded behaviour per feature. Cached data, a default, or a hidden section, decided in advance rather than improvised.
- Fail fast when degrading. A short timeout that drops to the fallback beats a long wait that degrades everything (see integration-resilience).
- Tell users what is unavailable. A visible, honest message beats a silently missing feature that reads as broken.
- Shed load deliberately under pressure. Rejecting a fraction of requests cleanly preserves the rest, where accepting everything fails all of it (see load-shedding).
- Test the degraded paths. They are the least exercised code and the most likely to be broken when needed (see chaos-engineering).
Boundaries
Degradation preserves partial service and does not prevent the underlying failure. Some operations cannot degrade, particularly financial and safety-critical ones. Degraded modes add code paths that need testing and can themselves fail.