Full-Stack Architecture Patterns

Circuit Breakers: Failure Windows, Probes and Safe Recovery

Configure circuit breakers around real failure semantics, bound recovery probes, and combine them with deadlines and concurrency limits.

Circuit Breakers: Failure Windows, Probes and Safe Recovery

Stop repeatedly attempting a failing operation

A circuit breaker uses recent outcomes to decide whether to admit another dependency call. It can reduce pressure during failures and give callers a predictable error quickly. It does not repair the dependency, cancel requests already running or provide a request deadline.

The familiar states are closed, open and half-open. Closed admits calls while recording outcomes. Open rejects calls according to policy. Half-open allows a bounded experiment to determine whether normal traffic should resume. Resilience4j circuit breaker documentation.

Define failure before choosing thresholds

An invalid user input is usually different from a dependency timeout. Treating every client error as dependency failure can open a circuit even while the service is healthy. Conversely, recording only thrown exceptions may miss HTTP failures if the client returns them as ordinary responses.

Record the selected operation, status classification, latency threshold and observation window. Use a minimum sample size so a low-volume service does not react to an unrepresentative fraction. Choose thresholds from service behavior and the caller's tolerance, rather than deriving them mechanically from a provider's uptime promise.

Resilience4j supports failure-rate and slow-call thresholds, minimum call counts and bounded half-open calls. Its sliding window is not a concurrency limit. A separate bulkhead is needed to restrict simultaneous work. Configuration and concurrency semantics.

Recovery is a controlled experiment

If every waiting caller becomes a probe when the cooldown ends, recovery can recreate the original overload. Limit probe admission and define how long incomplete probes may hold the half-open state.

Consider multiple application replicas. Each process may have its own breaker state and probe budget. Evaluate the combined recovery traffic rather than assuming one local probe means one request reaches the dependency.

In-flight outcomes also need consistent treatment during state changes. These concurrency details are a good reason to use and test a maintained implementation rather than copy a short demonstration class into production.

A fallback must remain truthful

A cached product description may be acceptable with a freshness policy. A stale price, account balance or authorization decision can have very different consequences. Do not return a successful payment result simply because the payment provider is unavailable.

For an uncertain payment outcome, retain the operation identifier and reconcile through the provider's documented mechanism. Any retry needs the appropriate idempotency semantics. A visible “status pending” can be more accurate than either a false success or an immediate second charge attempt.

Test transitions and caller behavior

Use a controlled dependency and deterministic timing in tests:

ScenarioRequired observation
Too few failures for the sample ruleCircuit remains in its configured state
Threshold crossedNew calls are rejected as specified
Cooldown endsOnly the configured probe budget is admitted
Probe fails or stallsRecovery policy is applied without unlimited traffic
Caller has already timed outLate completion does not corrupt operation state
Optional fallback succeedsMetrics still distinguish it from dependency recovery

Also verify deadlines, cancellation, retry limits and resource release. The broader pattern requires handling the failure as part of the application contract. Microsoft circuit breaker guidance.

The acceptance criterion is contained failure with correct user-visible behavior, not merely observing an “open” metric.

Sardar Mukhshaf

Sardar Mukhshaf

Full-Stack & DevOps Engineer

I build scalable web applications, secure backend systems, and production-ready cloud infrastructure. My engineering focus spans interface design, API architecture, deployment pipelines, and observability. Follow for more deep dives into system architecture, performance engineering, and emerging technologies.

More from the practice

Keep the useful ideas close.

Follow new articles with your preferred RSS reader.

Open the RSS feed ↗