Back to Posts
ArchitectureAPIs
Building Resilient APIs with the Circuit Breaker Pattern
2026-05-112 min read
In distributed systems, failures are inevitable. The circuit breaker pattern prevents a single failing service from cascading into a system-wide outage.
How It Works
A circuit breaker monitors calls to external services and "trips" (opens) when failures exceed a threshold. It has three states:
- Closed: Requests flow normally. Failures are counted.
- Open: Requests are immediately rejected with a fallback response.
- Half-Open: After a timeout, a limited number of test requests are allowed through.
Implementation
class CircuitBreaker {
private failures = 0;
private lastFailure = 0;
private state: 'closed' | 'open' | 'half-open' = 'closed';
constructor(
private threshold: number = 5,
private timeout: number = 30000
) {}
async call<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'open') {
if (Date.now() - this.lastFailure > this.timeout) {
this.state = 'half-open';
} else {
throw new Error('Circuit is open');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onSuccess() {
this.failures = 0;
this.state = 'closed';
}
private onFailure() {
this.failures++;
this.lastFailure = Date.now();
if (this.failures >= this.threshold) {
this.state = 'open';
}
}
}
Best Practices
- Use with retry logic: Combine with exponential backoff for transient failures.
- Monitor circuit states: Expose metrics for alerting when circuits open.
- Provide meaningful fallbacks: Return cached data or degraded functionality instead of errors.