Lesson 14 / 26
Circuit Breakers and Outlier Detection
Stop calling a failing dependency for a while so it can recover and callers fail fast.
Closed, open, half-open
A circuit breaker watches calls to a dependency. In the closed state calls pass normally. After enough failures it opens: calls are rejected immediately (fast fail) without hitting the struggling service, which gives it room to recover and stops callers wasting time. After a cool-down it goes half-open and lets a trial call through: success closes the circuit, failure reopens it. Meshes and gateways add related protections: outlier detection (temporarily ejecting a misbehaving instance from the pool), connection and request limits (bulkheads) and load shedding. Always provide a sensible fallback (cached data, a default, a clear error) for when the circuit is open.
A circuit breaker state machine, run
I ran this plain-Python model. Three failures open the circuit at t=2. Calls at t=3 and t=4 are rejected instantly. After the 10-second cool-down the call at t=13 is allowed as a trial, succeeds, and closes the circuit.
import hashlib, bisect, math, random
class Breaker:
def __init__(self, threshold=3, cooldown=10):
self.threshold, self.cooldown, self.fails, self.state, self.opened_at = threshold, cooldown, 0, "closed", None
def call(self, now, ok):
if self.state == "open":
if now - self.opened_at >= self.cooldown: self.state = "half-open"
else: return "rejected (fast fail)"
if ok:
self.fails = 0; self.state = "closed"; return "ok"
self.fails += 1
if self.state == "half-open" or self.fails >= self.threshold:
self.state, self.opened_at = "open", now
return "failed"
b = Breaker()
events = [(0, False), (1, False), (2, False), (3, True), (4, True), (13, True), (14, True)]
print([(t, b.call(t, ok), b.state) for t, ok in events])
Output:
[(0, 'failed', 'closed'), (1, 'failed', 'closed'), (2, 'failed', 'open'), (3, 'rejected (fast fail)', 'open'), (4, 'rejected (fast fail)', 'open'), (13, 'ok', 'closed'), (14, 'ok', 'closed')]
Envoy-style protections (illustrative)
In a mesh these are declared as policy rather than coded. This Istio DestinationRule limits connections and ejects instances that return repeated 5xx errors. Field names follow Istio; not run here.
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata: { name: orders }
spec:
host: orders
trafficPolicy:
connectionPool:
http: { http1MaxPendingRequests: 50, maxRequestsPerConnection: 100 }
outlierDetection:
consecutive5xxErrors: 5
interval: 10s
baseEjectionTime: 30s
maxEjectionPercent: 50Quick check: What does an open circuit breaker do?
- Encrypts the call
- Sends all traffic faster
- Deletes the service
- Rejects calls immediately to protect the failing service and callers
Answer
Rejects calls immediately to protect the failing service and callers — Fast failure gives the dependency time to recover and keeps callers responsive.