Stop calling a failing dependency before it drags you down with it. After a threshold of errors, open the circuit, fail fast for a cooldown period, then cautiously let traffic back in.
Rendering diagram…
Use a circuit breaker when you call something that can be down or slow and you want to fail fast instead of fail slow:
Retries and timeouts handle transient failures. A circuit breaker handles sustained failures — the thing is actually broken, and continuing to call it just wastes resources and amplifies the outage.
The breaker is a state machine with three states:
You need a rule for what counts as "failure" (HTTP 5xx, timeouts, specific exceptions) and a threshold (e.g. "5 failures in 30 seconds" or "failure rate > 50%"). Tune these to the dependency's actual behaviour, not a generic default.
Emit a metric on every state transition. "Circuit opened for payment-service" should be a visible alert — it means customers are about to feel pain.
Count-based thresholds (5 failures in a row) are noisy at low traffic. Rate-based thresholds (50% failure rate over 30 seconds with at least 20 calls) behave better under realistic load. Use rate-based unless traffic is tiny.
Wrong classification here produces circuits that trip when the dependency is fine.
What does your code do when the circuit is open? Options:
Pick one deliberately per call site.
One breaker per (dependency, operation) pair. A single global breaker for "all external calls" will trip on the first broken service and take your whole system down.
Your on-call should see which breakers are open at a glance. Half-open probes should be visible too — they tell you whether a dependency is recovering.
Gracefully handle transient API failures by retrying with increasing delays. Essential for any workflow that calls external services.
Capture workflow items that fail processing after all retry attempts are exhausted. Store them safely for investigation, manual correction, and replay — never silently lose data.