Skip to main content

CircuitBreaker

← all patterns

pattern

Monitors call outcomes and opens the circuit when failure or slow-call rates exceed configured thresholds — preventing calls to a degraded downstream service from propagating load.

01

State machine

State diagram: Closed transitions to Open when the failure or slow-call rate exceeds its
threshold. Open transitions to HalfOpen after waitDurationInOpenState elapses. HalfOpen transitions
to Closed when all permitted test calls succeed, or back to Open when any test call fails.
transition failure path (HalfOpen → Open)
  • Closed → Open — failure rate or slow-call rate exceeds its threshold, evaluated once the sliding window is full.
  • Open → HalfOpen — after waitDurationInOpenState elapses.
  • HalfOpen → Closed — all permitted test calls succeed.
  • HalfOpen → Open — any permitted test call fails.

02

Behavior

The CircuitBreaker maintains a sliding window of the last N call outcomes. After each call it recalculates the failure rate and the slow-call rate. If either rate exceeds its threshold, the circuit opens.

When open, all calls are rejected immediately without executing the operation. After a configured wait, the circuit moves to half-open and allows a small number of test calls through. If those succeed, the circuit closes. If any fail, it opens again.

A name is required. It appears in events and exceptions to identify which breaker fired. The current state is inspectable at any time — the Open state carries the timestamp it was entered and the remaining wait duration.

03

Rate thresholds

Both thresholds are expressed as fractions greater than 0.0 and up to 1.0 (0.0 itself is rejected at construction). A value of 0.5 means 50%. Thresholds are only evaluated once the sliding window has accumulated enough calls — before that, the circuit stays closed regardless of outcomes.

  • Failure rate — fraction of calls that threw a recorded exception.
  • Slow-call rate — fraction of calls that exceeded slowCallDurationThreshold.

04

Configuration

propertyrequireddescription
nameyesIdentifier used in events and exceptions (instance-specific)
failureRateThresholdnoFraction of failures that triggers open. Default: 0.5
slowCallRateThresholdnoFraction of slow calls that triggers open. Default: 1.0
slowCallDurationThresholdnoWhat counts as a slow call. Default: no limit
slidingWindowSizenoNumber of calls evaluated for rate calculation. Default: 10
waitDurationInOpenStatenoTime in Open before transitioning to HalfOpen. Default: 60s
permittedCallsInHalfOpenStatenoTest calls allowed in HalfOpen. Default: 3
recordOnnoException types that count as failures. Default: any Exception
ignoreOnnoException types that are not recorded
recordOnResultnoPredicate — record a failure based on return value
withListener()noSubscribe to circuit events (e.g. Opened, Closed, CallRecorded)
withClock()noUse a custom Clock instead of system (mainly for testing)
state()inspectGet current state (Closed/Open/HalfOpen) with remaining wait

05

Events & failure

  • Opened — circuit transitioned to Open. Carries: name, reason.
  • Closed — circuit transitioned to Closed. Carries: name, number of successful test calls.
  • HalfOpened — circuit transitioned to HalfOpen. Carries: name.
  • CallRecorded — a call outcome was recorded. Carries: name, success/failure, elapsed time, current failure rate.
  • Rejected — a call was rejected without executing, because the circuit was Open or HalfOpen with no test-call permits left.

Throws CircuitBreakerOpenException when a call is rejected — either the circuit is Open, or it is HalfOpen with every permitted test call already issued. Fields: name, and, only for the Open case, open since / remaining wait (both empty Optionals for a HalfOpen rejection, which has nothing equivalent to report).