You’ll receive an email confirming your submission.
Our team will contact you within 24–72 hours, depending on the complexity of your request.
By submitting, you agree to our [Privacy Policy] and consent to receive updates or consultation support from Open Reach Tech.
Please select the privacy consent checkbox.

components..title

components..description

components..title

components..description

You’ll receive an email confirming your submission.
Our team will contact you within 24–72 hours, depending on the complexity of your request.
By submitting, you agree to our [Privacy Policy] and consent to receive updates or consultation support from Open Reach Tech.
Please select the privacy consent checkbox.

Circuit Breaker – The System's Safety Switch

Portrait of Vu Bui
Vu BuiFrontend Developer

Learn the Circuit Breaker Pattern through a real-world scenario where a system faces massive traffic spikes while a third-party service becomes unavailable. Discover how it prevents cascading failures, protects resources, and improves system resilience.

Banner of Circuit Breaker – The System's Safety Switch

Circuit Breaker: The Lifesaving Switch During a Night of Market Panic

It was 2:00 AM, and a brutal flash crash hit the market. Top coins like BTC, ETH, and SOL were plunging in a straight vertical line. I sat frozen in front of my monitor, watching a massive wave of panicked users flood our trading platform to buy, sell, and swap tokens to cut their losses and salvage their positions.

At the absolute height of the chaos, Decibel—the third-party service our platform integrates with to process transactions for these top coins—suddenly choked. It failed to respond to the gargantuan influx of orders. On the user interface, an endless loading spinner spun continuously, heightening our users' fear of losing money. Desperate, they started spamming the trade button, clicking it dozens of times in a row. Millions of requests aggressively slammed into our backend, completely draining the database connection pool. As the CPU utilization pinned at 100%, I knew our exchange was seconds away from crashing entirely.

Right at that fatal moment, a sharp "CLICK" echoed from the source code. The Circuit Breaker—a defensive mechanism I had engineered into the system beforehand—instantly went to work.

After quietly recording 5 consecutive timed-out requests sent to Decibel, it realized this external connection gateway was completely paralyzed. Without a single millisecond of hesitation, it cut the circuit, transitioning instantly into the OPEN state.

The next incoming tsunami of user requests was immediately blocked right at the backend’s front gate, preventing them from even touching the core system. The platform promptly triggered a fail-fast error response: "System is overloaded, please try again in 15 seconds."

Thanks to that ruthless rejection, my servers escaped the death grip. It freed up the clogged connection pools, keeping core features like account connections and balance displays alive. The system secured 15 precious seconds to breathe, allowing the Decibel service to stabilize before gracefully shifting to half-open to test for recovery. The cascading system collapse was completely averted.

What Exactly is a Circuit Breaker?

A Circuit Breaker is a design pattern used to prevent an application from repeatedly trying to execute an operation that's almost certain to fail. Think of it exactly like an electrical circuit breaker in your house. When a short circuit or overload is detected (equivalent to a service failing), the breaker trips to temporarily stop the electrical current (requests) from passing through. Once the external service stabilizes, the breaker automatically closes to let everything resume normal operations.

The primary goals of this pattern are:

  • Prevent cascading failures: If one service goes down, ensure it doesn't drag the rest of the ecosystem down with it.
  • Optimize resources: Stop wasting server compute power on requests bound for a broken service.
  • Self-healing: Periodically test the failed service to see if it has recovered.
  • Increase resilience: An absolute necessity for modern distributed systems and microservices.

Operating States

A Circuit Breaker typically operates across 3 fundamental states:

Closed

The system runs normally. All requests pass through freely to the external service.

  • The breaker silently counts the number of failed requests.
  • If the failure count breaches a specified threshold (e.g., 3 consecutive failures), it immediately trips into the Open state.

Open

The external service is assumed to be "dead." No more requests are routed to it.

  • Every single incoming request is intercepted and rejected instantly via a fail-fast mechanism.
  • It waits for a predefined cooldown period (timeout), before transitioning into the Half-Open state to scout the situation.

Half-Open

The breaker enters a trial phase to see if the service has recovered.

  • It starts sending a few test requests.
  • If these test requests are successful, it assumes the system is healthy and reverts back to the CLOSED state.
  • If any error occurs during this phase, it immediately trips back to the OPEN state and resets the cooldown timer.

Implementation Example in JavaScript

Here is a straightforward object-oriented implementation:

class CircuitBreaker {
  private failures = 0;
  private lastFailureTime = 0;
  private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';

  constructor(
    private failureThreshold: number = 5,
    private recoveryTimeMs: number = 60000 // 1 minute
  ) {}

  async execute<T>(operation: () => Promise<T>): Promise<T> {
    if (this.state === 'OPEN') {
      if (Date.now() - this.lastFailureTime > this.recoveryTimeMs) {
        this.state = 'HALF_OPEN';
        console.log('Circuit breaker transitioning to HALF_OPEN');
      } else {
        throw new HttpError(503, 'Circuit breaker is OPEN - external service unavailable');
      }
    }

    try {
      const result = await operation();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }

  private onSuccess() {
    this.failures = 0;
    this.state = 'CLOSED';
  }

  private onFailure() {
    this.failures++;
    this.lastFailureTime = Date.now();
    
    if (this.failures >= this.failureThreshold) {
      this.state = 'OPEN';
      console.error(`Circuit breaker OPEN after ${this.failures} failures`);
    }
  }

  getState() {
    return this.state;
  }
}

And here is how you use it in practice:

// Simulating an unstable external API that fails occasionally
const unstableApi = async () => {
  const shouldFail = Math.random() < 0.3; // 30% failure rate
  if (shouldFail) {
    throw new Error("API failed");
  }
  return "API success";
};

// Instantiate Circuit Breaker: Trip after 3 errors, wait 10s before retrying
const breaker = new CircuitBreaker(3, 10000); 

const callApiWithBreaker = async () => {
  try {
    const result = await breaker.execute(() => unstableApi());
    console.log("Result:", result);
  } catch (err: any) {
    console.warn("Error:", err.message, "| State:", breaker.getState());
  }
};

// Fire a request every 2 seconds to test the behavior
setInterval(() => {
  callApiWithBreaker();
}, 2000);

When Should You Use It?

You should heavily consider incorporating this pattern when:

  • Your application interacts with third-party APIs (payment gateways, mail delivery, SMS OTP).
  • You are building architecture where multiple microservices depend heavily on one another.
  • Network communications are unstable or prone to transient faults.
  • The system handles high traffic surges, putting downstream dependencies at risk of being crushed.

Instead of writing this from scratch, you can leverage highly optimized, production-grade libraries:

  • opossum – A feature-rich circuit breaker for Node.js with built-in metrics and fallbacks.
  • cockatiel – A resilience and transient-fault-handling library for JS (Retry, Timeout, Circuit Breaker).
  • resilience4j (Java) – The industry standard in the Spring Boot ecosystem.

Real-World Use Cases

On the Frontend

Have you ever encountered a scenario where a server bottlenecks due to heavy user traffic, yet the client applications keep blindly firing network requests until everything times out, preventing the server from ever recovering? This is exactly where a frontend Circuit Breaker saves the day. By blocking user requests locally once the failure rate hits a ceiling, it gives the server breathing room to auto-recover. When you see messages like "Please try again in 30 seconds," you are seeing a Circuit Breaker in action.

Real-world scenario:

  • You are building an event ticketing platform (e.g., a massive concert sale).
  • At opening time, tens of thousands of users smash F5 to buy tickets.
  • The server bottlenecks, throwing 504 Gateway Timeout or 503 Service Unavailable errors.
  • The frontend keeps sending automated background requests to check seat availability, suffocating the server and knocking it offline permanently.

Consequences without a Circuit Breaker:

  • Users aggressively spam refresh -> thousands of requests/sec -> the server chokes.
  • Every request times out -> the UI freezes up -> users get highly frustrated.
  • The server loses any chance of auto-recovery because the stampede of traffic never stops.

On the Backend

A prominent use case involves backend integrations with metered, paid third-party services (such as OpenAI or Google Maps). Typically, even if a request returns an error due to a timeout or invalid response, the API provider might still deduct your credits or charge against your quota if the request hit their servers. Implementing a Circuit Breaker ensures your backend fails fast when a vendor goes down, protecting you from wasting company funds on requests destined to fail.

Ultimately, engineering teams across both Frontend and Backend should actively implement this pattern to optimize network traffic, mitigate systemic risks, and bolster the overarching stability of the architecture.