Stackbook Logo
resilience

Graceful Degradation Framework

Intent

Design features to fall back to reduced but useful behavior when dependencies fail, instead of failing completely.

Problem

Modern applications depend on many services, and any one of them can be slow or unavailable. When every feature is treated as mandatory, a failure in a minor dependency such as recommendations takes down a critical flow such as checkout. Teams discover the coupling only during outages.

Forces

    Solution

    Graceful Degradation Framework

    Graceful degradation means a system loses features in a controlled order instead of failing as a whole. The aim is to protect the core value of the product while non-essential capabilities step aside. It is a design practice as much as a runtime mechanism.

    How it works

    The framework has three layers.

    • Criticality map: each feature and dependency is tagged critical, important, or optional, based on its effect on the primary user journey and revenue.
    • Fallback ladder: for each optional capability, define successive fallbacks, from fresh data to cached data to static defaults to omitting the component.
    • Triggers: automatic triggers come from timeouts, error rates, and circuit breakers; manual triggers come from feature flags that operators flip during incidents.

    The user interface should communicate the state, for example showing a banner or replacing a widget with a neutral placeholder, rather than showing an error.

    Implementation steps

    1. List user journeys and trace every dependency each one calls.
    2. Mark each dependency as hard or soft. A soft dependency must never fail the request.
    3. For each soft dependency, write the fallback and its staleness limit, for example serve cached recommendations up to 24 hours old.
    4. Implement fallbacks at the boundary of the dependency client, with a short timeout and a circuit breaker.
    5. Add operator flags to force degraded modes, such as disabling search suggestions to relieve a database.
    6. Inject faults in staging and periodically in production to confirm each fallback activates.
    7. Add the degraded states to runbooks and status page templates.

    Common pitfalls

    • Treating a timeout as an error rather than a trigger, so the fallback is never reached.
    • Fallbacks that call the same failing dependency through another path.
    • Cache fallbacks with no expiry, serving dangerously old data such as prices.
    • Forgetting that fallback code runs under stress and must be cheaper than the primary path.
    • Silent degradation that no one notices until customers complain.

    Metrics to watch

    • Fallback activation rate per feature and dependency.
    • Percentage of requests served in degraded mode.
    • Age of data served from fallback caches.
    • Core journey success rate while degraded.
    • Time to detect and time to exit degraded mode.

    Example configuration

    features:
      recommendations:
        criticality: optional
        timeout_ms: 150
        fallbacks:
          - type: cache
            max_age: 24h
          - type: static
            value: popular_items
          - type: hide
        breaker:
          error_threshold: 0.5
          open_seconds: 30
        ops_flag: degrade.recommendations
      checkout:
        criticality: critical
        fallbacks: []
    

    Key takeaways

    • Decide up front which features may be lost and in what order.
    • Every optional dependency needs a tested fallback and a staleness limit.
    • Use timeouts and breakers to trigger fallbacks quickly.
    • Give operators manual switches and tell users the truth.
    • Exercise fallbacks with fault injection or they will not work when needed.

    ✓ When to Use

    • •Applications with optional enrichment features such as recommendations or personalization
    • •User journeys where core transactions must survive partial outages
    • •Systems with many third-party dependencies
    • •Products with strict availability targets

    ✗ When Not to Use

    • •Strict correctness domains where stale or partial results are unacceptable
    • •Features with no meaningful reduced form
    • •Very small systems with a single dependency

    Pros

    • +Keeps core journeys available during partial failure
    • +Reduces blast radius of dependency outages
    • +Makes dependency criticality explicit
    • +Improves user trust through predictable behavior

    Cons

    • −Fallback paths add code and test burden
    • −Untested fallbacks fail when first used
    • −Stale data can mislead users
    • −Complexity grows with the number of modes

    Cost Profile

    Infrastructure

    Operational

    Cognitive

    Failure Modes

      Alternatives

        Related Patterns

          Competency Domains

          reliability opsrequirements constraintsdistribution communication