Circuit Breaker Pattern

Sercan Çakır
Insider Engineering
4 min readJan 10, 2022

In the real world, circuit breakers are used to prevent electrical faults. To prevent bigger problems, the circuit breaker is automatically activated in case of a problem.

The circuit breaker systemlifecycle

Developers like to adapt real world solutions to software. In this article, we will talk about circuit breakers for software.

The Theory

Many applications need to communicate with different sources. Sometimes we may need to connect the DB or cache driver, sometimes we use synchronous remote calls. Each factor affects the app’s health. Because, sometimes we may not be able to communicate with them for any reason.

It will be a waste of both resources and time to perform a transaction knowing that we will get a failure. Also, the rollback scenario may be hard on large systems. Instead of this if we know the transaction may be a failure, we can prevent it instead of execute.

That’s exactly the mission of the circuit breaker.

Important Variables

To implement a circuit breaker, it is useful to know some keywords for your workflow. We need to keep some data to determine state.

Threshold

It keeps the maximum number of failures allowed. If the number of failures exceeds this value, the circuit breaker will be open.

Timeout

When the Circuit Breaker is in the open state, it must allow limited transactions after waiting for a while. Because we need to repair the state. Here it is defined how long to wait after the last failed transaction.

Failure Transactions

We need to keep count of failure and last failure timestamp. This data may be kept in Redis, DB or etc for not losing these values. However, these values may be array. Sometimes, you need to separate failures status.

For example, the exchange service requests should be executed even if the weather service is blocked.

States

Generally, the Circuit Breaker pattern has 3 states. We don’t have best practices for changing the state. Depending on the application needs the state changer strategies may be different.

Closed

The default state is closed. This means the count of failures did not exceed the threshold and the system is working as expected. In this state all transactions will be processed without preventing.

All transactions will be processing in closed state

Open

When the number of failures exceeds the threshold, the circuit breaker will change state to open. The transactions are blocked immediately without being attempted.

In this state your application can have a different strategy. For example, you can return cached data when the API requests are blocked.

All transactions will be prevented in open state

Half-Open

In this state, the circuit breaker allows some transactions. The state may be closed when the transactions are successful. But, if the transactions continue to fail the state will be open.

Your application may follow different strategies when returning open or closed state.

For example, sometimes you can reset the previous failures when a transaction executed successfully or you can stay half-open state for some failures. In this case no best practices. Because each application’s requirements are different.

Limited transactions will be allowed in half-open state

TL;DR

The Circuit Breaker pattern prevents the execution of a potentially failing operation.

Example

Now we will prepare a very simple class of circuit breaker. Normally circuit breaker states need to be kept as permanently. We keep it in the Redis.

For simplicity in this example, we will keep it simple with class property.

This is a very simple class. The circuit breaker will be open when 20 transactions have failed. Operations are inhibited when the circuit breaker is in open mode. However, some transactions are retried 30 seconds after the last failure. And the new status is determined according to the transaction’s status.

Example usage:

Output:

string(25) "the default state: closed"
string(23) "after 20 failures: open"
string(24) "after wait 10 secs: open"
string(29) "after wait 30 secs: half-open"
string(26) "after successfully: closed"
string(25) "after again failure: open"

References

For more about this pattern:

--

--