It’s tempting to think a circuit breaker shields a struggling downstream service from load. Mostly it doesn’t — and that isn’t its job. Its job is to stop the caller from destroying itself waiting on a dependency that’s already down.
When a dependency starts failing, a naive caller keeps sending requests that pile up against timeouts, holding threads and connection-pool slots hostage. One sick dependency quietly becomes your outage. A breaker watches the failure rate; once it crosses a threshold it opens — failing fast, instantly, without making the call — for a cooldown window. Then it half-opens, lets a trickle through to test recovery, and closes again if they succeed.
Failing fast is the entire point: it frees the caller’s resources and lets it degrade gracefully instead of hanging. That’s why a breaker only works with tight timeouts (it needs a fast failure signal) and pairs with backoff (so the half-open probe doesn’t become a stampede). It’s a bulkhead against latency, not a favor to the thing you’re calling.