When Should Not Use Circuit Breaker Pattern
The Circuit Breaker Pattern is a fault-tolerance pattern that prevents a service or system from making repeated requests to a failing component. However, it should not be used in scenarios where the cost of a failed request is negligible, or the failure can be retried immediately without significant consequences.
Scenarios Where the Circuit Breaker Pattern Should Not Be Used
-
Idempotent Operations with Negligible Costs
If the operation is lightweight, idempotent, and has negligible resource cost, retrying it immediately may not require a circuit breaker.
Example: Fetching static configuration data from a resilient and fast cache service like Redis. -
Critical Operations That Must Always Try to Execute
If the operation must always attempt execution regardless of failures (e.g., logging or metrics collection), using a circuit breaker could block necessary functionality. -
Intermittent Failures With Immediate Recovery If failures are known to be temporary and retrying quickly can resolve the issue, a retry mechanism without a circuit breaker might be more appropriate.
Example
A Scenario Where Circuit Breaker Should Not Be Used: Fetching Static Data
Suppose a service needs to fetch a list of configuration settings from a cache (e.g., Redis) on startup.
Without Circuit Breaker
public List<String> fetchConfigurations() {
try {
return redisClient.get("configurations"); // Lightweight and fast
} catch (Exception e) {
System.out.println("Retrying...");
return redisClient.get("configurations"); // Retry immediately
}
}
This approach works because fetching configuration data:
- Is lightweight.
- Does not overload the system even if retried multiple times.
- Can handle intermittent failures quickly (e.g., Redis temporarily unavailable).
With Circuit Breaker
Using a circuit breaker here might block all configuration fetching if the cache becomes temporarily unavailable, leading to unnecessary delays.
public List<String> fetchConfigurations() {
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("fetchConfigBreaker");
Supplier<List<String>> fetchSupplier = CircuitBreaker.decorateSupplier(circuitBreaker,
() -> redisClient.get("configurations"));
try {
return fetchSupplier.get();
} catch (CallNotPermittedException e) {
System.out.println("Circuit is open, cannot fetch configurations.");
return Collections.emptyList(); // Return default or fallback
}
}
Why Circuit Breaker is Not Ideal Here
- Configuration fetching is not resource-intensive.
- Fallback (empty configuration) might disrupt the service unnecessarily.
- Redis downtime is often short-lived, and retries can resolve it quickly.
In contrast, the circuit breaker pattern is better suited for protecting systems from expensive, long-lasting failures, such as calling an external payment gateway or an unreliable third-party API.