Circuit Breaker
Protects the system from cascading failures by cutting off calls to a struggling service.
Context
A dependency (external API, DB, cache) starts to fail/timeout. Your application keeps calling it, exhausting threads and propagating latency.
Problem
- Calling something known to be broken wastes resources.
- Massive retries worsen the incident.
Solution
A breaker monitors failures. If they exceed a threshold, it transitions to Open and immediately rejects calls. After a period, it attempts in Half-Open and decides.
#Example in C# — Polly
using Polly;
using Polly.CircuitBreaker;
var breaker = Policy
.Handle<HttpRequestException>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 5,
durationOfBreak: TimeSpan.FromSeconds(30),
onBreak: (ex, ts) => log.LogWarning("Breaker opened {Span}", ts),
onReset: () => log.LogInformation("Breaker closed"));
var response = await breaker.ExecuteAsync(() => httpClient.GetAsync("/api/orders"));Tradeoffs
| Pro | Con |
|---|---|
| Prevents cascading failures | Some requests fail fast even if the service has recovered |
| Allows remote service time to recover | Configuring thresholds requires observability |
#Variants
- Bulkhead (isolates thread pools per dependency).
- Retry with exponential jitter (often combined with Circuit Breaker).
#extra #resilience