Trade-offs · Production decisions
Circuit breaker early trip vs late trip
How to choose circuit breaker thresholds, window size and open time, with the cost of tripping too early and too late worked out.
Asked at: SDE-2Senior
The decision
A circuit breaker is code around the calls to one dependency. When many calls fail, it opens, and later calls fail at once without waiting. After a pause it enters a half-open state and lets a few trial calls through. It closes again if they succeed. Three settings decide its behaviour. The threshold is how many failures make it open. The window is how many calls it looks at. The open time is how long it stays open. An early trip protects your workers but may refuse calls that would have worked. A late trip lets slow calls fill your workers first.
Choose an early trip when
- The dependency is optional and you have a good fallback, such as a saved price or a hidden recommendation box. A refused call costs little.
- A failing call is slow. Each slow call holds a worker, so waiting costs more than refusing.
- Traffic is high, so the breaker sees enough calls to judge fast.
- The dependency is fragile, and fewer calls help it recover.
Choose a late trip when
- There is no fallback, as with a payment call. An open breaker returns the same error as the failure, only faster, so you gain only the worker time that waiting would cost.
- The dependency has a normal error rate that is not zero, for example 2 percent. A low threshold would trip all the time.
- Traffic is low. A small window is mostly noise.
- A false trip is expensive, because the open time is long or the calls carry money.
The numbers that change the answer
The defaults of one popular library, Resilience4j, are a good starting picture. It looks at the last 100 calls and opens when 50 percent have failed. It needs at least 100 calls before it judges. It stays open for 60 seconds and then allows 10 trial calls. Its slow-call limits are 60 seconds and 100 percent of calls, so slow calls alone rarely trip it. Treat them as a starting point.
Window size and noise. Assumption: a healthy dependency fails 2 percent of calls by chance, and each call fails independently of the others. Real failures come in bursts, so treat the results as a guide. Take a window of 10 calls, as separate groups of 10. A sliding window checks after every call, so it trips even more often.
- Trip at 2 failures of 10 (20 percent). The chance of 2 or more failures is 1 minus the chance of 0 or 1.
- Chance of 0: 0.98 to the power of 10 = 0.8171. Chance of 1: 10 x 0.02 x 0.98 to the power of 9 = 0.1667. So the chance is 1 - 0.8171 - 0.1667 = 0.0162, which is 1.6 percent.
- At 400 calls per second there are 40 groups of 10 per second. Expected false trips: 40 x 0.0162 = 0.65 per second. The breaker would open about every 1.5 seconds on a healthy service.
- Trip at 5 failures of 10: the chance is about 0.0000007 (the sum for 5 to 10 failures). That is safe.
So a small window needs a high threshold. A larger window allows a lower one.
Blind time at low traffic. At 2 calls per second and a minimum of 100 calls, the breaker needs 100 / 2 = 50 seconds to judge. Until then it cannot trip. At 400 calls per second it needs 100 / 400 = 0.25 seconds.
Cost of a late trip. Assumption: an API server has 200 workers and sends 400 calls per second to a price service. When every call runs to the timeout, the workers held are calls per second x time per call.
- Timeout 300 ms: 400 x 0.3 = 120 workers, which is 60 percent of 200.
- Timeout 2 seconds: 400 x 2 = 800 workers needed. The 200 are all busy after 200 / 400 = 0.5 seconds.
Cost of an early trip. Each second of a false open refuses 400 healthy calls. A false open of 10 seconds refuses 400 x 10 = 4,000 calls. With a 60-second open time, 24,000.
Cost of staying open too long. The dependency recovers 5 seconds after it fails. A breaker open for 60 seconds refuses calls for 60 - 5 = 55 more seconds. That is 55 x 400 = 22,000 refused calls that would have worked. A breaker with 10 seconds open, plus trial calls, loses (10 - 5) x 400 = 2,000.
Trial calls. After the open time, 3 to 10 trial calls go through. Too few, and one unlucky failure can reopen the breaker. Too many, and a recovering service takes a burst. Assumption: 5 trial calls, and the breaker closes when at least 4 succeed. In a simple design any failed trial reopens it.
What breaks with each choice
Tripping too early.
- Healthy traffic is refused. Users see errors from a dependency that is fine.
- A breaker that flaps (open, closed, open) hides real problems.
- What you do: a larger window, a minimum number of calls, and a failure rate, not a single failure count.
Tripping too late.
- Workers fill with slow calls, and unrelated pages fail. This is the 200 workers in 0.5 seconds case.
- The dependency keeps getting full traffic while it is down, so it recovers later.
- What you do: a shorter timeout, a pool of workers for each dependency (a bulkhead), and a trip on slow calls, not only on errors.
Open time wrong.
- Too short: trial calls hit a service that is still down, and the breaker opens again and again.
- Too long: you refuse calls after recovery, as in the 22,000 example. Use a short open time that grows after each failed trial.
One breaker for everything. One failing shard opens the breaker for all shards. Use one breaker for each dependency and each shard.
What it costs
All numbers here are assumptions.
- Money: nothing for the library. A fallback needs a saved copy of data and a place to store it.
- People: a day to add a breaker, and three to five days to tune it with a load test that fails the dependency on purpose.
- Time to change your mind: the settings are configuration. Change them in minutes, one dependency at a time, and watch the refused-call rate.
How each level answers
The question is: "The recommendations service is slow. How do you protect checkout?"
SDE-1: A circuit breaker stops calls to a failing service for a while, so callers fail fast. It has three states: closed, open and half-open.
SDE-2: I wrap the recommendations call in a breaker with a short timeout and a fallback of an empty list. Recommendations are optional, so I trip early.
Senior: At 400 calls per second with a 2-second timeout, 800 workers are needed and 200 exist, so the pool is gone in 0.5 seconds. I use a 300 ms timeout (120 workers), a window of 100 calls and a threshold of 50 percent. I put the call in its own pool of workers, and I tune the open time to 10 seconds, not 60.
Staff: The business question is which features may fail without hurting revenue: checkout stays up, and recommendations may go. I write that list with product, and each dependency owner owns its breaker settings. Every quarter a failure test proves them, and we watch healthy calls refused and the time from recovery to close.
Say it in the interview
I would use one breaker for each dependency, with a window of 100 calls and a threshold of 50 percent. For an optional service I trip early and return a fallback. The risk is refusing healthy calls, so I keep the open time near 10 seconds and use trial calls to close it.
Common mistakes
- A window of 10 with a low threshold. At 2 percent normal errors, 1.6 percent of windows trip. The breaker flaps.
- Counting only errors. A slow service holds workers without any error. Trip on slow calls too.
- One breaker for all dependencies or shards. One failure takes everything down.
- A breaker without a fallback or a pool. It turns slow errors into fast errors, but the page still fails.
Sources
- Resilience4j, circuit breaker defaults (failure rate 50, window 100, minimum calls 100, open 60,000 ms, 10 half-open calls): https://resilience4j.readme.io/docs/circuitbreaker (opens in a new tab) (checked 26 Oct 2026).
- Microsoft Azure Architecture Center, "Circuit Breaker pattern" (states; open too long or half-open too soon; a default value; breakers for shards): https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker (opens in a new tab) (checked 26 Oct 2026).
- The traffic, the 2 percent normal error rate, the timeouts, the recovery time and the trial settings are assumptions made for teaching. The false trip chances are calculations from the binomial formula, and they assume that calls fail independently.
Understand the trade-off. Practise explaining your choice.
In an AI mock interview, the interviewer can push on a choice like this one: it changes a number and asks if your answer still holds.