Skip to main content

Circuit Breaker Strategy

The circuit breaker reactive resilience strategy shortcuts the execution if the underlying resource is detected as unhealthy. When a circuit is broken, subsequent calls are immediately rejected without attempting execution.
The Circuit Breaker strategy rethrows all exceptions, including those that are handled. Its role is to monitor faults and break the circuit when a threshold is reached, not to manage retries.

When to Use Circuit Breaker

Use the circuit breaker strategy when:
  • Protecting downstream services from being overwhelmed during failures
  • Failing fast is better than making users wait for timeouts
  • You want to give a failing system time to recover
  • Preventing cascading failures in microservices architectures
  • Implementing the “stop doing it if it hurts” principle

Installation

Circuit States

The circuit breaker has four states:
1

Closed (Normal)

Operations execute normally. The circuit monitors for failures.
2

Open (Broken)

Circuit is broken. All operations are immediately rejected with BrokenCircuitException.
3

Half-Open (Testing)

After the break duration expires, the circuit allows one test operation to check if the system has recovered.
4

Isolated (Manual)

Circuit is manually held open. Operations are blocked until manually closed.

Usage

Basic Circuit Breaker

Custom Thresholds

Dynamic Break Duration

Handling HTTP Status Codes

Monitoring Circuit State

Manual Circuit Control

State Transition Events

Configuration Options

Predicate
Defines which results and/or exceptions are counted as failures.
double
default:"0.1"
The failure-success ratio that will cause the circuit to break. 0.1 means 10% of sampled executions must fail.
int
default:"100"
The minimum number of executions that must occur within the sampling duration before the circuit can break.
TimeSpan
default:"30 seconds"
The time period over which the failure-success ratio is calculated.
TimeSpan
default:"5 seconds"
Fixed time period for which the circuit will remain broken before attempting to reset.
Func<BreakDurationGeneratorArguments, ValueTask<TimeSpan>>
default:"null"
Dynamically calculates the break duration using runtime information like failure count. If set, BreakDuration is ignored.
CircuitBreakerManualControl
default:"null"
Enables manual control of circuit state via IsolateAsync() and CloseAsync() methods.
CircuitBreakerStateProvider
default:"null"
Enables retrieving the current circuit state for health reporting and monitoring.
Func<OnCircuitClosedArguments, ValueTask>
default:"null"
Invoked after the circuit transitions to the Closed or Isolated state.
Func<OnCircuitOpenedArguments, ValueTask>
default:"null"
Invoked after the circuit transitions to the Open state.
Func<OnCircuitHalfOpenedArguments, ValueTask>
default:"null"
Invoked after the circuit transitions to the HalfOpen state.

Best Practices

Place circuit breaker inside retry strategy. This allows retry to respect the broken circuit and fail fast when the circuit is open.
Balance between sensitivity and stability:
  • Too sensitive: circuit breaks on minor issues
  • Not sensitive enough: failing system gets overwhelmed
Start with defaults and tune based on your service’s behavior.
Use StateProvider to expose circuit state in health checks and monitoring dashboards. This provides visibility into system health.
Don’t use a single circuit breaker for multiple endpoints. Isolate failures by creating separate circuits for each dependency.
Too short: may not give the system enough time to recover Too long: increases user-perceived downtimeUse BreakDurationGenerator for adaptive break durations that increase with repeated failures.

Examples

HTTP Client with Circuit Breaker

Circuit Breaker with Retry and Fallback

Health Check Integration

  • Closed: Normal operation. Circuit monitors for failures and can automatically transition to Open.
  • Isolated: Manually held open. Circuit won’t automatically close; requires manual intervention via CloseAsync().
No. During normal operation (Closed state), exceptions are thrown as normal. When Open or Isolated, it throws BrokenCircuitException or IsolatedCircuitException instead.
Use the ResiliencePipelineProvider with keyed services or maintain a dictionary of circuit breakers per user/tenant identifier.
It’s not recommended. Create separate circuit breakers for each dependency to isolate failures and avoid one failing service affecting others.