Skip to main content

Patterns

Circuit breaker (closed / open / half-open)

Protection against cascading failures of API dependencies

Circuit breaker isolates calls to a failing dependency (SuperPDP, BulkGate SMS, eIDAS-certified signature partner) to prevent an external outage from propagating timeouts to the entire app. Three states. CLOSED (nominal): calls pass normally, failures counted over a sliding window. Above the threshold (e.g. 50% failures over 20 calls), breaker goes OPEN: all calls fail immediately (fail fast) without touching the dependency, for a cooldown (e.g. 30s). After cooldown, HALF-OPEN state: N test calls pass through; if successful, back to CLOSED; otherwise OPEN with doubled cooldown. Implementations: `opossum` (Node.js), `resilience4j` (Java), custom Laravel middleware. Metrics exposed to Datadog/Sentry to alert on OPEN transitions.

Key facts

  • 3 states: CLOSED (nominal), OPEN (fail-fast), HALF-OPEN (probing)
  • Typical threshold: 50% failures over 20 calls → OPEN
  • Initial cooldown 30s, doubled on each OPEN return (max 5 min)
  • Critical metric: rate of OPEN transitions per minute
  • Libs: opossum (JS), resilience4j (Java), custom Laravel middleware

Code example

import CircuitBreaker from 'opossum';

const superpdpCall = async (payload: unknown) =>
  fetch('https://api.superpdp.fr/v1.beta/invoices', {
    method: 'POST',
    body: JSON.stringify(payload),
  }).then(r => r.json());

const breaker = new CircuitBreaker(superpdpCall, {
  timeout: 5000,           // ms
  errorThresholdPercentage: 50,
  resetTimeout: 30_000,    // 30s cooldown
  rollingCountTimeout: 60_000,
  rollingCountBuckets: 10,
});

breaker.on('open',     () => metrics.incr('superpdp.breaker.open'));
breaker.on('halfOpen', () => metrics.incr('superpdp.breaker.halfopen'));
breaker.fallback(()    => ({ status: 'queued_for_retry' }));

See also

Your cookie preferences

We use cookies to improve your experience. Essential cookies are always active. Cookie policy.