Picture a service that depends on something external like another microservice, a database, or a third-party API. Most of the time, it works fine. But what happens when that dependency starts failing or, worse, starts hanging?
If every request takes 30 seconds to timeout, those requests start piling up. Threads and connections get tied up, latency increases, and eventually even unrelated requests can start slowing down. One small failure can then spread across the system and cause much bigger problems. This is called a cascading failure, and it's one of the problems the Circuit Breaker pattern is designed to help prevent.
The pattern gets its name from electrical circuit breakers. When too much current flows through a circuit, the breaker trips and cuts the connection to prevent further damage. It doesn't keep pushing power through a fault but it stops. The software version works in a similar way. A circuit breaker sits in front of a risky call and monitors its failures. If too many requests fail, it stops sending new requests to that dependency.
Instead of waiting 30 seconds for a timeout, the request fails immediately. This prevents wasted resources and helps stop the failure from spreading. After some time, it allows a few requests through to check if the dependency has recovered. If they succeed, everything goes back to normal. If they fail, the circuit opens again and waits before trying later.
States
The whole pattern comes down to three states:
Closed The normal state. Requests flow through as usual while failures are monitored. As long as they stay below the threshold, nothing changes.
Open Too many failures have occurred, so the breaker trips. New requests are stopped immediately instead of calling the failing dependency. The system can return an error or fallback instead.
Half-Open After a cooldown, the breaker cautiously allows a few requests through to check if the dependency has recovered. If they succeed, it goes back to Closed. If they fail, it returns to Open.
The Half-Open state is probably the most interesting part to me. It's not simply on or off but there's a small testing phase before the system fully trusts the dependency again.
Checking a single request
What stood out to me most is that a circuit breaker doesn't fix the underlying problem. If the dependency is down, it's still down. What it changes is how the rest of the system responds. Instead of every request waiting for the failing call to timeout, the failure stays contained to the part that's actually having trouble. It also gives room for a proper fallback. We could return cached data, a simpler response, or a clear message that the service is temporarily unavailable. And it helps the failing dependency recover too. If a database is already overloaded, constantly sending more retries to it is only going to make things worse. A circuit breaker gives the dependency some breathing room while protecting the rest of the system.
Before looking into it, I thought the Circuit Breaker pattern was one of those system design terms that gets thrown around without much explanation. Now it makes a lot more sense. The idea is pretty simple which is to stop calling something that's already struggling, fail fast, and carefully check again before trusting it.


Top comments (0)