The circuit breaker pattern stops a failing downstream service from taking the rest of your system down with it. Named after the electrical device that trips to stop a current overload, a software circuit breaker watches for repeated failures when calling another service and, past a threshold, stops sending requests to it entirely for a while — failing fast instead of piling up timeouts and slow requests that can exhaust threads, connections, or memory upstream.
What changed in 2026
- Circuit breaker logic moved increasingly into service mesh and API gateway layers (Istio, Envoy, cloud load balancers), so teams get the pattern configured centrally rather than implementing it inside every service by hand.
- Adaptive thresholds — circuit breakers that adjust their trip sensitivity based on recent traffic patterns rather than a single fixed number — became more common in mature platforms.
- Observability integration improved, with circuit breaker state changes (closed, open, half-open) now commonly surfaced directly in dashboards and alerts rather than buried in logs.
The three states
A circuit breaker moves between three states. Closed is normal operation: requests pass through, and failures are counted. Open happens once failures cross a threshold: requests are rejected immediately without even attempting the call, protecting both the caller and the struggling downstream service. Half-open is a recovery probe state: after a cooldown period, the breaker allows a small number of test requests through; if they succeed, it closes again, and if they fail, it reopens.
Circuit breaker vs related patterns
| Pattern |
What it does |
Solves |
| Retry |
Re-attempts a failed call, often with backoff |
Transient, short-lived failures |
| Circuit breaker |
Stops calling a service after repeated failures |
Sustained outages, avoiding cascading failure |
| Timeout |
Caps how long a call is allowed to take |
Slow responses that would otherwise hang a request |
| Bulkhead |
Isolates resources (threads, connections) per dependency |
One dependency exhausting shared resources |
| Fallback |
Returns a default or cached response instead of failing |
Graceful degradation when a dependency is unavailable |
These patterns are complementary, not competing — a robust service typically combines timeouts, retries with backoff, a circuit breaker, and a fallback response.
When to use a circuit breaker
Use one anywhere your service calls another service or external API over the network, especially when that dependency is not fully within your control and could degrade independently of your own service health. It matters most in systems built from many small services (see the strangler fig pattern for one common way such systems get built incrementally), where one slow dependency can otherwise cause a cascading failure across unrelated parts of the system.
Common mistakes
- Setting the failure threshold too low, tripping the breaker on ordinary transient blips and making the system less available than the dependency actually warrants.
- No fallback behavior. A circuit breaker that trips and simply returns an error to the end user is only half the pattern; a cached or default response often keeps the feature partially working.
- Forgetting the half-open probe delay, causing the breaker to hammer a recovering service with full traffic the instant it flips back to closed, potentially re-tripping it immediately.
- Applying one breaker per service instead of per dependency-and-operation, which can trip unrelated calls to the same service that were actually healthy.
FAQ
Is a circuit breaker the same as a retry mechanism?
No, they solve different failure modes and work well together. Retries handle brief, transient failures by trying again. A circuit breaker handles sustained failures by stopping calls altogether for a period, preventing the retries themselves from making an outage worse.
Where should a circuit breaker live - in application code or infrastructure?
Either works; many teams now prefer infrastructure-level breakers (in a service mesh or gateway) for consistency across services, while others keep it in application code (libraries like resilience4j or Polly) for finer control over fallback behavior.
What happens to requests while the circuit is open?
They fail immediately, typically returning a fallback response or a clear error, rather than waiting for a timeout. This is the core benefit: failing fast protects upstream resources instead of letting requests pile up.
Does a circuit breaker help with domain-driven service boundaries?
Indirectly. Well-defined service boundaries, as covered in domain-driven design basics, make it clearer which calls are true external dependencies that need breaker protection versus internal calls that do not.
Where to go next