Skip to content
← Insights

Graceful Degradation in Applications: What to Keep When a Dependency Fails

Decide which features to keep, limit, or stop when a dependency fails. This practical framework helps protect data, inform users, and restore service safely.

Diagram of an application keeping some features available and limiting others when a dependent service fails

When an application depends on internal or external services, the failure of one of them should not automatically bring everything to a halt. However, keeping every feature running as if nothing happened can also lead to inconsistent data, duplicate operations, or decisions based on outdated information. Designing graceful degradation means deciding in advance which capabilities remain available, which are limited, and which must be blocked while a dependency is unresponsive.

The decision should protect the business process, not just technical availability. For each feature, consider which service it needs, what happens if that service is unavailable, how long the interruption can be tolerated, and how consistency will be restored afterward. This lets the team offer a useful alternative without hiding the problem or taking unnecessary risks.

What graceful degradation means

What graceful degradation means

An application is degrading gracefully when, in response to a failure or an inadequate response from a dependency, it retains a deliberate set of features with explicit limits. It is not a complete copy of the service, nor a promise that everything will keep working. It is a policy for how the application behaves during partial failures.

It differs from several related mechanisms:

  • Offline mode: lets people use certain features without connectivity and, in some cases, sync changes later. Graceful degradation can also apply when the network is available but a particular service has failed.
  • Retries: try a failed request again, usually with limits and delays. On their own, they do not determine what a person should see or do while the dependency remains unavailable.
  • Graceful degradation: defines the user experience and business rules during a failure, including which operations are allowed, what data they can use, and what restrictions apply.

For example, if a recommendation service fails, the application might show a general selection and keep search available. If a required payment validation service fails, allowing a charge to proceed anyway could create a greater risk than temporarily interrupting that action.

Map each feature to its dependencies and impact

Start with a map of product capabilities, not an isolated inventory of services. For each user-facing feature, record which dependencies it needs and what outcome it produces. A useful entry includes the operation, required service, data read or written, user impact, and consequences of an incorrect result.

Then assess two dimensions: the impact of being unable to complete the feature and the potential harm if it is completed with incomplete or incorrect information. These are not the same. A delay in loading content may be inconvenient, while accepting a transaction without checking its status can cause losses or reconciliation problems.

Begin by classifying features into three groups:

  • Can be kept: capabilities that do not rely on the failed dependency, such as viewing content already available locally.
  • Can be limited: useful actions whose scope can be restricted, such as displaying stored data with its last-updated date or allowing a draft to be saved without submitting it.
  • Must be stopped: operations whose correctness depends on a check that cannot be performed, such as confirming an irreversible action without validating its conditions.

The classification should account for alternatives and consequences for the teams involved. Product can decide which parts of the experience remain valuable; engineering and operations should confirm which failures they can detect and what guarantees the systems provide. Also review indirect dependencies: a feature may appear independent but still need a later validation to complete the process.

Choose between limited functionality, cached data, and a manual alternative

The right option depends on how old the data can be, whether the operation changes state, and whether later reconciliation is possible. Not every cache is safe for every use: data that is useful for guiding a query may be unsuitable for authorizing an operation.

  • Cached data: use it when a read remains useful even if the information is not fully up to date. State how old it is and do not present it as a current confirmation. Define when it is no longer acceptable; if you cannot establish that limit based on business needs, do not use it for sensitive decisions.
  • Reduced functionality: offer part of the feature, such as viewing information but not changing it, or preparing a request without submitting it. Explain which step remains pending and what will be needed to complete it.
  • Manual alternative: this may be appropriate when there is a clear procedure, assigned owners, and a record-keeping process afterward. Without these controls, manual work can create duplicates and become a parallel source of data.
  • Temporary block: this is preferable when the operation cannot be performed safely or verified later. Restrict the affected action, not necessarily the entire application.

Before allowing deferred writes, specify how operations are identified, stored, and retried; what response the person receives; and how conflicts are resolved. If there is no safe rule for these cases, keeping the intent as a draft is usually less risky than claiming the action was completed.

Block operations that could leave data inconsistent

The key question is whether the system can distinguish between a request that was never received, one that was processed but whose response was lost, and one that is still pending. If it cannot, repeating a sensitive operation without safeguards could execute it more than once. Retries should be limited and suited to the type of request; for actions with side effects, design mechanisms to recognize duplicates and check the result before trying again.

Stop or limit an operation when:

  • it requires a validation that is unavailable and there is no approved alternative rule;
  • it could produce an irreversible effect or one that is difficult to compensate for;
  • it is not possible to tell whether an earlier request was completed;
  • the stored data is older than the freshness threshold acceptable for that decision.

If a compensating action is available, document who can initiate it and how it is recorded. Do not assume a compensating action is equivalent to undoing the original effect: it may require operational intervention, review, or communication with the affected person. The policy should reflect these limitations.

Communicate the limitation and restore service carefully

The message should explain which feature is limited, what the person can do now, and whether they need to repeat any step. Avoid statements such as “completed” when a request has only been saved as pending. Do not promise a recovery time that the team cannot guarantee, either. A clear status reduces impulsive retries and avoidable support contacts.

When the dependency recovers, do not blindly reactivate everything that was left pending. Check the actual status, process operations in a defined order, detect duplicates, and record the results. If changes conflict, apply an agreed rule—for example, review before overwriting—and retain enough traceability to investigate discrepancies.

Recovery should have observable conditions. Confirm that the dependency is responding consistently, that its results are valid, and that the application can complete the normal workflow. Then remove restrictions in a controlled way. If symptoms return, the system should be able to limit the feature again rather than oscillating between available and failed states.

Test decisions and measure the outcome

Test decisions and measure the outcome

A degradation policy that exists only in a document does not prove that the application applies it correctly. Simulate outages, high latency, partial errors, and late responses from each important dependency. Check the interface as well as logs, pending operations, and duplicate handling. Include recovery and reconciliation tests, not just tests for entering limited mode.

Review technical and business signals together. Technical indicators include dependency errors and response times, retry volume, and the duration of degradation. Business indicators include blocked operations, pending requests, detected conflicts, and cases requiring manual intervention. Improved availability is not enough if it increases inconsistent transactions or support workload.

As a practical rule, answer and validate four questions for every feature: what is kept, what is limited, what is blocked, and how recovery is confirmed. If the team cannot answer them, the strategy is not yet complete. Graceful degradation turns an inevitable failure into an explicit decision: preserve the value that remains safe and defer what depends on a guarantee that is temporarily unavailable.

Fuentes y referencias

  1. Cloud Native GlossaryCloud Native Computing Foundation
  2. Site Reliability EngineeringGoogle