A circuit breaker stops a service from repeatedly calling a dependency that is failing. Like an electrical breaker, it "trips" after too many failures: further calls fail immediately (or use a fallback) instead of waiting on timeouts, which gives the struggling dependency room to recover and keeps the caller responsive.
In simple words
Like the fuse box at home: when an appliance keeps shorting, the fuse trips so the whole house doesn't catch fire. After a while you try switching it back on; if it's still faulty, it trips again.
Stop hammering a failing dependency, then test it carefully before letting full traffic through.
Why It Exists
When a downstream service slows down, callers pile up requests waiting on timeouts. Threads and connections run out, the caller becomes slow too, and the failure cascades up the chain. Retries make it worse by multiplying load on the service that is already struggling.
How It Works
failures > threshold
CLOSED ------------------------> OPEN
(calls pass, (calls fail fast / fallback,
count failures) for a cool-down, e.g. 30 s)
^ |
| trial calls succeed | cool-down over
| v
+------------------------- HALF-OPEN
trial call fails -> (let a few trial calls through)
back to OPEN
Closed: normal; track error rate or consecutive failures over a window.
Open: reject immediately with an error or a fallback (cached data, a default, "try later").
Half-open: after the cool-down, allow a few trial requests; success closes the circuit, failure reopens it.
Works Together With
Timeouts on every remote call (without them, nothing ever "fails" fast enough to count).
Retries with exponential backoff and jitter, and a retry budget, so retries don't become a storm.
Bulkheads: separate connection/thread pools per dependency, so one bad dependency can't exhaust everything.
Fallbacks: degrade gracefully (hide recommendations, show cached prices) instead of failing the whole page.
Key Pointers
Fail fast when a dependency is down; don't queue up behind timeouts.
Three states: closed → open → half-open → closed.
Pair with timeouts, backoff and fallbacks; alone it only stops the bleeding.
Libraries/meshes provide it: Resilience4j, Polly, Envoy/Istio outlier detection.
Follow-up Questions
How is this different from a retry?
A retry tries again hoping the failure was transient. A circuit breaker stops trying when failure looks persistent. Retries without a breaker can overwhelm a recovering service.
What fallback would you use for a product recommendations service?
Show popular items from a cache or hide the section entirely. The page still loads, which matters more than personalisation.