Resilience Policies
withCircuitBreaker
Stop calling a failing backend to prevent cascading failures.
The withCircuitBreaker policy implements the circuit breaker pattern. When the backend fails too many times, it "opens" the circuit and immediately rejects requests without calling the backend, giving it time to recover.
Usage
import { fixedWindow, withCircuitBreaker } from '@ratelock/redis'
const limiter = await fixedWindow({ ... })
const circuitBreaker = withCircuitBreaker(limiter, {
failureThreshold: 5, // open after 5 consecutive failures
recoveryTimeoutMs: 30_000, // wait 30s before trying again
})Configuration Options
Prop
Type
States
| State | Behavior |
|---|---|
| Closed | Normal operation. Requests go through to the backend. |
| Open | Requests are rejected immediately. No backend calls. |
| Half-Open | One probe request is allowed. If it succeeds, the circuit closes. If it fails, the circuit reopens. |
Error Context
When the circuit is open, the thrown error includes the last error as its cause:
try {
await limiter.check('user:123')
} catch (err) {
console.log(err.message) // "Circuit breaker is open"
console.log(err.cause) // The original error that opened the circuit
}Built-in Alternative
For most cases, use the built-in circuitBreaker option at creation time instead:
import { fixedWindow } from '@ratelock/redis'
const limiter = await fixedWindow({
url: 'redis://localhost:6379',
limit: 100,
windowMs: 60_000,
circuitBreaker: { failureThreshold: 5, recoveryTimeoutMs: 30_000 },
})See Resilience Policies for when to use standalone vs built-in.
How is this guide?
Last updated on