Circuit breakers: separate a recovery state machine from resource bounds
Compare closed/open/half-open recovery with Envoy's per-proxy upstream resource limits and their enforcement scope.
On this page
The question for today
What you’ll understand
- Trace a specified closed/open/half-open breaker protocol.
- Distinguish Envoy resource circuit breaking from that classic state machine.
- Calculate nominal fleet-wide budgets without claiming coordinated global enforcement.
Circuit breaker can name two related but different mechanisms. A classic application breaker changes between closed, open, and half-open states to control recovery attempts. Envoy's documented circuit breaking also limits upstream resources such as outstanding requests, pending work, connections, and retries. Both can reject work, but their state, scope, and proof obligations differ.
A classic breaker needs explicit transition rules
In a closed state, calls are allowed and their classified outcomes update a failure detector. Crossing a defined threshold opens the breaker, causing selected calls to fail quickly instead of reaching the dependency. After a configured delay, a half-open state admits a bounded probe population. Success can close the breaker, while failure can reopen it. Define the observation window, error classes, timer origin, number of probes, and concurrent access rules. Without these choices, the three-state drawing is a vocabulary list rather than an executable protocol.
A successful probe must test the dependency behavior the guarded operation needs. A trivial health response may not establish that a costly authenticated transaction works. Concurrent callers need coordination so half-open does not accidentally admit thousands of probes. Reopening or closing can also affect requests already in flight; the protocol must state whether they continue and how their late results are counted. A breaker is usually local to a process, operation, or dependency key unless an explicit distributed mechanism coordinates it.
Envoy resource limits protect a different boundary
Envoy v1.40.0 documents limits per upstream cluster and priority for maximum connections, pending requests, outstanding requests, active retries, and connection pools. A pending request waits for a suitable ready pool connection, which differs from an already outstanding upstream request. HTTP/2 multiplexing means a connection count is not a request-concurrency count. These resource mechanisms do not require the exact closed/open/half-open failure-window protocol described above. Inspect overflow counters and the relevant resource rather than inferring the cause from a generic circuit-open label.
The limits are distributed across proxy instances rather than coordinated as one service-wide quota. Worker threads within a proxy share limits, but the documented implementation can have eventual-consistency races, and connection allocation has specific exceptions. Therefore a configured limit is not a universal exact hard ceiling on every live statistic. A fleet of twelve proxies each configured with a nominal fifty-request budget does not thereby enforce a fifty-request global budget. Scope, priority, cluster identity, and the number of callers determine the aggregate offered concurrency.
Rejection must participate in the end-to-end policy
A fast rejection prevents some waiting and resource consumption at the protected boundary, but an upstream client can immediately retry and recreate the load. Coordinate retry budgets, deadlines, backpressure, and admission policy across layers. Classify whether a rejection is overload, policy denial, no eligible endpoint, or application failure so the caller does not retry every response identically. Monitor useful completions alongside rejection counts: a low queue can mean healthy service or simply that all work is being rejected.
The queue lab exposes pressure without simulating either breaker. Reset, set λ=4 and μ=3, predict the four-unit initial backlog grows by one unit per second, then Play or Step. Separately Reset, set λ=2 and μ=3, predict it drains in four seconds, then Play or Step. There is no capacity cap, closed/open/half-open state, or rejection control in the instrument. Use its uncapped growth to explain why a real bounded queue needs an explicit admission rule, then draw the chosen recovery-state schedule separately.
Work it through
Trace a small recovery protocol and its separate budget
A fictional breaker opens after three classified failures in its defined window, waits two seconds, then admits exactly one probe. Separately, twelve proxies each have a nominal fifty-request upstream budget.
After the third counted failure, the classic breaker enters open and rejects guarded new calls. At two elapsed seconds it enters half-open and permits one probe under a coordinated admission rule.
If that probe succeeds under the protocol's definition, return to closed; if it fails, return to open and restart the specified wait. Other concurrent callers do not all become probes.
The independent nominal proxy budgets sum to 12×50=600 requests. That arithmetic neither implements the classic state machine nor creates a coordinated fifty-request fleet quota.
The recovery protocol determines when calls may resume, while nominal resource budgets describe how much independent proxy work is configured. They must not be conflated.
The living notebook
Explore the model
Interactive lab · queue
Why unbounded waiting needs an admission policy
Reset, set λ=4 and μ=3, predict growth of one queued unit per second, then Play or Step. Separately Reset, set λ=2 and μ=3, predict the four-unit backlog drains in four seconds, then Play or Step. The fluid instrument has no breaker states, admission cap, or rejected-request counter.
- Fluid backlog
- 4
- Net rate · λ − μ
- −1 /s
- M/M/1 mean residence
- 1 s
Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forRecovery state machines and resource limits are distinct mechanisms that both need an end-to-end overload policy.
Pause & reason
Check your understanding
Your turn
Try it yourself
A classic breaker enters open at elapsed time 10 s and waits 3 s before one half-open probe. The probe starts at 13 s and fails at 13.2 s. Under a policy restarting the wait from that failure, when is the next probe eligible?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Apply the stated timer origin rather than the original opening time.
Compare with the solution
The failed probe reopens the breaker at 13.2 s, so the next eligible probe time is 16.2 s. This is a fictional protocol with one probe and a precisely stated timer origin; it is not a claim about every application library or Envoy resource circuit breaking.
Keep the idea
Take it with you
- A classic breaker needs explicit failure, timing, and probe-transition rules.
- Envoy's resource circuit limits have different counters and scopes.
- Local rejection and independent budgets do not automatically coordinate fleet-wide recovery.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.