Circuit breaker
also called provider circuit breaker · breaker · failure breaker
There are three states and the transitions between them are the whole design. Closed is normal: traffic flows and consecutive failures are counted. Open means every request is refused locally, with no network call at all — this is the state that buys back the latency. Half-open is the recovery test: exactly one request is allowed through, and its result decides everything. Success closes the breaker and resets the counter; failure re-opens it and restarts the cooldown from scratch. It is worth deriving half-open from the clock rather than storing it as a separate state — open plus elapsed cooldown reads as half-open — because a breaker that has to be woken by a timer is a breaker that can get stuck open when the timer is lost.
What counts as a failure is the decision that separates a useful breaker from one that takes healthy providers out of rotation. An HTTP 400 caused by a malformed request says nothing whatsoever about the provider’s health; if it counts, one client sending bad JSON in a loop can open the circuit for everybody else. So only genuinely transient classes should count — a timeout, a rate limit, a server error — and everything that is a property of the request or the credential should not. This has a pleasant consequence: an expired or revoked vendor key produces a fast, typed authentication error on every call rather than an open circuit, which points the operator at the environment variable instead of at an apparent outage. Threshold and cooldown are ordinary tuning; five consecutive transient failures to open and thirty seconds to a probe is a defensible starting point for a model provider, where an outage is usually minutes rather than milliseconds.
Scope matters as much as the thresholds. The unit is the dependency — one breaker per upstream provider and credential, not one per model and not one for the estate — because a provider is what actually goes down. Beyond that, there must be exactly one breaker object per dependency in the process: if the request path holds one map of breakers and the metrics endpoint builds another, the dashboard will report healthy while traffic is being refused, and the operator will spend the outage arguing with the graph. For the same reason, reloading provider configuration must not construct fresh breakers, or every configuration change silently forgives the outage history that was about to protect you.
A breaker sits between two other mechanisms and is often confused with both. Inside a provider, a capped retry with jittered backoff handles the single failed attempt. Above it, a fallback policy decides which provider to try next. The breaker decides only whether a given candidate is worth calling at all: an open circuit means that candidate is skipped and the chain continues to the next one, so a request usually still succeeds, just not there. That ordering is why a breaker is not a substitute for a failover policy. It answers whether to call; the class of the failure answers where to go instead.
The honest limits are three. First, a threshold on consecutive failures never trips for a provider that is failing forty per cent of calls — nothing reaches five in a row — so a breaker tuned this way protects against outages and not against degradation; a failure-rate window catches that case but is harder to reason about and slower to react. Second, counting a timeout as a failure is right for availability and ambiguous for money, because a timeout cannot prove the upstream did not execute and bill the request. Third, a breaker measures transport, not truth: a provider returning prompt 200s full of nonsense is perfectly healthy as far as the state machine is concerned, and detecting that is the job of evaluation, not of a breaker.
Five failures, thirty seconds, one probe
A provider starts returning 503s. Requests one to four are retried in place and fail; the counter reaches four and the circuit is still closed. The fifth transient failure opens it. For the next thirty seconds every request that would have gone to that provider is refused locally in microseconds and moves straight to the next candidate in its chain — no connection, no timeout, no charge. At thirty seconds the breaker reads as half-open and the next request is allowed through as a probe. If it returns 200, the circuit closes and the counter resets to zero. If it fails, the circuit re-opens for another thirty seconds, having spent exactly one request to find out. A malformed request arriving from a client at any point in that window does not count either way.
What circuit breaker is routinely confused with
- Rate limiting
- A rate limiter caps traffic you are entitled to send, to protect a budget or a downstream service. A breaker stops traffic you have evidence will fail, to protect your own latency and error budget. One is a quota decided in advance; the other is a reaction to observed behaviour.
- Kill switch
- A breaker engages itself from observed failures and releases itself after a cooldown, and it is scoped to a dependency. A kill switch is engaged by a named person for a stated reason, is released only by a person, is scoped to an identity — an agent, a team, an estate — and does not care whether anything is failing.
- Retry with backoff
- A retry is bounded state within one request: the same provider, the same credential, a few more attempts. A breaker is state that persists across requests, so the hundredth caller does not have to rediscover what the first ninety-nine already established.
Related terms
Typed failover
Typed failover is a fallback policy that decides whether to try the next provider from the class of the failure rather than from a retry count: transient classes — a timeout, a rate limit, a server error — move to the next candidate, while failures that are properties of the request or the credential stop where they are. It exists because some failures are identical at every vendor, and because one of them is a refusal that a second attempt would convert into an apparent success.
Model routing
Model routing is the resolution, at the moment of the call, of a requested model name to a concrete provider and model, together with the ordered list of alternatives that may serve it if the first one fails. It lets a client that only knows one model name be pointed at a different vendor, region or price without the client changing, and it is where a multi-provider estate’s data-handling and cost constraints are actually applied.
Kill switch
A kill switch is an operator-engaged control that refuses all further requests from a named agent, a team, or an entire estate, checked before every other governance decision and released only by a person. It is the control that has to work when everything more precise has failed, which is why it is scoped by identity rather than by rule, and why engaging it records who did it and what reason they gave.
Where Token Observe does this
The definition above is the field's, not the product's. This is the part of the product that implements it, for a reader who wants to see one.
The terms next to this one
Where the money goes, why providers disagree about how to count it, and what a spend control has to do to be a control rather than an alert.
Definitions are the easy part.
The glossary is written to be useful whether or not you ever buy anything. If you have got to the point of deciding how to implement one of these in your own estate, say what your agents do and you will get a straight answer about what it would actually take.
no form · no qualification step · no sales desk · the other three ways in