The problem
When a downstream service is slow or down, its callers keep sending requests and waiting for timeouts. Threads and connections pile up behind the slow calls, latency climbs, and the failure spreads upstream as a cascading failure. Meanwhile the struggling service gets hammered with traffic (and retries) at exactly the moment it needs relief.
How it works
A circuit breaker wraps calls to a dependency and watches their outcomes. It is a small state machine:
- Closed: calls pass through. Failures are counted, or a failure rate is computed over a sliding window.
- Open: once the threshold is crossed, calls are rejected immediately, without touching the network, and the caller falls back.
- Half-open: after a cooldown, a limited number of trial calls go through. Success closes the breaker; a failure opens it again for another cooldown.
When to use it
- Calls to remote services or shared resources that can fail or slow down: HTTP APIs, databases, third-party SaaS.
- When a fast, degraded answer beats a slow failure: cached data, defaults, "try again later".
- Not for purely in-process calls, and not as a substitute for fixing an unreliable dependency.
Trade-offs
- Tuning matters. Too sensitive and it trips on noise; too lax and it trips too late. Prefer a failure rate with a minimum call volume and a slow-call threshold over a raw count.
- You need a real fallback. Without one, an open breaker only makes you fail faster.
- Each instance learns on its own. Per-instance breakers only see their own traffic, so every replica trips separately.
- Pair it with timeouts and careful retries. A hung call never counts as a failure without a timeout, and retries should treat "breaker open" as non-retryable so they don't hammer the circuit.
Implementation notes
- Libraries: Resilience4j (Java), Polly (.NET), opossum (Node.js), pybreaker (Python), gobreaker (Go).
- Infrastructure: service meshes and proxies offer the same idea without code changes. Examples are Envoy's outlier detection and circuit-breaking thresholds, and Istio
DestinationRuleoutlierDetection. - Observe it: emit a metric or event on every state change. A breaker that opens is one of the clearest alerts you can get.