Problem
A basic open and closed breaker with static thresholds can flap, trip too late, or protect the wrong thing. Across many instances and dependencies, uncoordinated breakers either overreact or fail to prevent cascading overload.
Extend basic circuit breakers with adaptive thresholds, fallbacks, and coordination to protect systems from persistent downstream failure.
A basic open and closed breaker with static thresholds can flap, trip too late, or protect the wrong thing. Across many instances and dependencies, uncoordinated breakers either overreact or fail to prevent cascading overload.
The advanced circuit breaker goes beyond tripping on consecutive errors. It watches rates over sliding windows, treats slowness as failure, recovers gradually, and cooperates with other resilience mechanisms.
Each breaker tracks calls in a count-based or time-based sliding window. It opens when the failure rate or slow-call rate exceeds a threshold, but only after a minimum number of calls, which prevents tripping on tiny samples. After a wait duration it moves to half-open and permits a limited number of probe calls. Success closes the breaker; failure reopens it, optionally with exponential growth of the wait duration. While open, callers receive a fallback such as cached data, a default, or a clear degraded error.
# Resilience4j circuit breaker
resilience4j.circuitbreaker.instances.inventory:
slidingWindowType: TIME_BASED
slidingWindowSize: 60
minimumNumberOfCalls: 20
failureRateThreshold: 50
slowCallDurationThreshold: 2s
slowCallRateThreshold: 60
waitDurationInOpenState: 30s
permittedNumberOfCallsInHalfOpenState: 5
Teams adopt this approach when a dependency fails or slows down for extended periods; many callers could overload a recovering service. It is a poor fit when calls are local and cannot fail independently, or when dependencies are so fast and reliable that protection adds only complexity. The central tensions are sensitivity vs stability; fail fast vs availability of partial results; local autonomy vs coordinated state. The main benefits are that it delivers: prevents calls to known-failing dependencies; gives recovering services room to heal; slow-call detection catches brownouts, not just errors; events provide valuable operational signal. The main costs to budget for are: thresholds need tuning and can misfire; per-instance state yields inconsistent views; fallbacks add code paths that need testing; open breakers can mask problems if not alerted on. Governance typically looks like this: platform provides shared library and defaults; teams own thresholds. Expect adoption cost to be low to medium: library adoption plus tuning, and a best fit for teams running multiple interdependent services. Critics point out that mis-tuned breakers cause outages that would not have occurred, and that per-instance breakers can behave erratically at low traffic volumes. Treat these concerns as design inputs, and revisit the decision as traffic, team size, and failure history change.