Dung (Donny) Nguyen

Senior Software Engineer

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

  1. 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.

  2. 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.

  3. 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:

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

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.