Circuit breaker
Stop hammering a failing dependency by opening a circuit after repeated failures.
Add circuit when an upstream API is flaky or failing and you want the stitch
to stop hammering it. After a run of failures the breaker opens and calls
fast-fail for a cooldown: the stitch backs off, giving the unhealthy dependency
room to recover before a single trial call probes it again — and shielding your
app from the slow, cascading failures a dead upstream would otherwise pull it
into.
Example
import { } from 'stitchapi';
const = ({
: 'https://api.example.com',
: '/orders',
: { : 5, : 30_000 },
});After 5 consecutive failures the breaker opens; for the next 30 seconds calls
to orders() fast-fail instead of hitting api.example.com.
Options
The breaker moves through four states. It starts closed (calls pass
through). After failures consecutive failures it trips open and
calls fast-fail for cooldown. It then goes half-open and lets a single
trial call through: a success closes it and clears the count, another
failure re-opens it for a fresh cooldown. The breaker emits progress
events with phase circuit. The positional form names both knobs at once:
circuit: [5, '30s'] ≡ circuit: { failures: 5, cooldown: '30s' }.
failures and cooldown are both required — failures is
the count of consecutive failures that trips the breaker open, and cooldown
is the fast-fail window after opening, before a half-open trial is allowed.
cooldown is the only knob on that boundary: the instant the fast-fail
window ends is the instant the trial is admitted. There is no separate probe
timer, because a call is either rejected or let through — a phase between the
two would have to behave exactly like one of them.
key is a store namespace: give two stitches the same key plus a shared
store to share one breaker, so a failing
host opens the circuit for every stitch that talks to it. The default key is the
stitch/host key — which also means a multi-tenant fleet shares one breaker until
you say otherwise, and
one customer's revoked token, everyone's outage
measures which isolation channels are automatic and which are a string you have
to remember to write. When the point of the breaker is to hand traffic to a
second vendor, failing over to the backup provider
covers the routing it does not do for you.
Anti-pattern: don't lean on the default in-memory breaker across
multiple workers or instances — the counter is process-local, so each
replica tallies its own failures and failures trips per process, letting a
failing host take many times the hits you intended before every circuit
opens. Give the stitches a shared key plus a durable store so one
breaker spans the fleet. See Pluggable
store.
While the breaker is open, a call fast-fails instead of reaching the dependency — see STITCH_CIRCUIT_OPEN for what callers see and how to handle it.
See Reference → Config types for every field.