PHPackages                             syastrebov/circuit-breaker - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. syastrebov/circuit-breaker

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

syastrebov/circuit-breaker
==========================

Circuit breaker wrapper for microservices and api calls.

v0.0.9(4mo ago)01.3k↓86%2MITPHPPHP ^8.3CI passing

Since Jan 30Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/syastrebov/Circuit-Breaker)[ Packagist](https://packagist.org/packages/syastrebov/circuit-breaker)[ RSS](/packages/syastrebov-circuit-breaker/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (7)Versions (10)Used By (2)

PHP Circuit Breaker implementation for microservices and API calls.

- Laravel package:
- Symfony package:

Install
-------

[](#install)

```
composer require syastrebov/circuit-breaker
```

Usage
-----

[](#usage)

### Simple usage:

[](#simple-usage)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\RedisProvider;

$redis = new \Redis();
$redis->connect('redis');

$circuit = new CircuitBreaker(new RedisProvider($redis));
$response = $circuit->run(
    $name,
    function () {
        // call your api
        return '{"response": "data"}';
    }
);

// {"response": "data"}
echo $response;
```

### Use fallback:

[](#use-fallback)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\RedisProvider;

$redis = new \Redis();
$redis->connect('redis');

$circuit = new CircuitBreaker(new RedisProvider($redis));
$response = $circuit->run(
    $name,
    // action
    function () {
        throw new \RuntimeException('unable to fetch data');
    },
    // fallback
    function () {
        // call your api
        return '{"response": "cached data"}';
    }
);

// {"response": "cached data"}
echo $response;
```

### Use exception:

[](#use-exception)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\RedisProvider;
use CircuitBreaker\Exceptions;

$redis = new \Redis();
$redis->connect('redis');

$circuit = new CircuitBreaker(new RedisProvider($redis));

try {
    $response = $circuit->run(
        $name,
        // action
        function () {
            throw new \RuntimeException('unable to fetch data');
        }
    );
} catch (UnableToProcessException $e) {
    // handle exception
}
```

Config
------

[](#config)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\RedisProvider;
use CircuitBreaker\CircuitBreakerConfig;

$redis = new \Redis();
$redis->connect('redis');

$circuit = new CircuitBreaker(new RedisProvider($redis), new CircuitBreakerConfig(
    // Prefix
    prefix: 'api',
    // Number of attempts within run() action
    retries: 5,
    // Number of failed attempts to change state to 'OPEN'
    closedThreshold: 2,
    // Number of succeed attempts to change state to 'CLOSED'
    halfOpenThreshold: 2,
    // Delay between retries within run() action in microseconds
    retryInterval: 1000,
    // TTL of OPEN state in seconds
    openTimeout: 60,
    // If true and no fallback defined returns NULL otherwise throws UnableToProcessException
    fallbackOrNull: true
));
```

Supported Drivers
-----------------

[](#supported-drivers)

### Redis:

[](#redis)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\RedisProvider;

$redis = new \Redis();
$redis->connect('redis');

$circuit = new CircuitBreaker(new RedisProvider($redis));
```

### Redis cluster:

[](#redis-cluster)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\RedisProvider;

$redis = new \RedisCluster(
    'my cluster',
    [
        'redis-node-1:6379',
        'redis-node-2:6379',
        'redis-node-3:6379',
    ],
    1.5,
    1.5,
    true
);

$circuit = new CircuitBreaker(new RedisProvider($redis));
```

### Predis:

[](#predis)

```
use CircuitBreaker\CircuitBreaker;
use Predis\Client;

$predis = new Client([
    'host' => 'redis',
]);

$predis->connect();

$provider = new PredisProvider($predis);
```

### Predis cluster:

[](#predis-cluster)

```
use CircuitBreaker\CircuitBreaker;
use Predis\Client;

$nodes = [
    'redis-node-1:6379',
    'redis-node-2:6379',
    'redis-node-3:6379',
];

$options = [
    // 'redis' (server-side) or 'predis' (client-side)
    'cluster' => 'redis',
];

$predis = new Client($nodes, $options);

$predis->connect();

$provider = new PredisProvider($predis);
```

### Memcached:

[](#memcached)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\MemcachedProvider;

$memcached = new \Memcached();
$memcached->addServer('memcached', 11211);

$circuit = new CircuitBreaker(new MemcachedProvider($memcached));
```

### MySQL:

[](#mysql)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\DatabaseProvider;

$table = 'circuit_breaker';

$pdo = new \PDO("mysql:host=mysql;dbname=database", 'user', 'password');
$pdo->prepare("
    CREATE TABLE IF NOT EXISTS $table (
        prefix VARCHAR(255) NOT NULL,
        name VARCHAR(255) NOT NULL,
        state ENUM('closed', 'open', 'half_open'),
        state_timestamp INT,
        half_open_attempts INT,
        failed_attempts INT,
        CONSTRAINT prefix_name_unique UNIQUE (prefix, name)
    );
")->execute();

$provider = new DatabaseProvider($pdo, $table);
```

### PostgreSQL:

[](#postgresql)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\DatabaseProvider;

$table = 'circuit_breaker';

$pdo = new \PDO("pgsql:host=postgres;dbname=database", 'user', 'password');
$pdo->prepare("
    DO $$
    BEGIN
        IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'state_enum') THEN
            CREATE TYPE state_enum AS ENUM ('closed', 'open', 'half_open');
        END IF;
    END $$;
")->execute();
$pdo->prepare("
    CREATE TABLE IF NOT EXISTS $table (
        prefix VARCHAR(255) NOT NULL,
        name VARCHAR(255) NOT NULL,
        state state_enum NULL,
        state_timestamp INT,
        half_open_attempts INT,
        failed_attempts INT,
        CONSTRAINT prefix_name_unique UNIQUE (prefix, name)
    );
")->execute();

$provider = new DatabaseProvider($pdo, $table);
```

### SQLite:

[](#sqlite)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\DatabaseProvider;

$table = 'circuit_breaker';
$databaseFile = __DIR__ . '/database.sqlite';

$pdo = new \PDO("sqlite:$databaseFile");
$pdo->prepare("
    CREATE TABLE IF NOT EXISTS $table (
        prefix VARCHAR(255) NOT NULL,
        name VARCHAR(255) NOT NULL,
        state TEXT CHECK(state IN ('open', 'half_open', 'closed')),
        state_timestamp INTEGER,
        half_open_attempts INTEGER,
        failed_attempts INTEGER,
        CONSTRAINT prefix_name_unique UNIQUE (prefix, name)
    );
")->execute();

$provider = new DatabaseProvider($pdo, $table);
```

Logger (optional)
-----------------

[](#logger-optional)

```
use CircuitBreaker\CircuitBreaker;
use CircuitBreaker\Providers\RedisProvider;
use Monolog\Logger;

$circuit = new CircuitBreaker(
    provider: new MemoryProvider(),
    logger: new Logger('circuit_breaker_channel')
);
```

Run tests
---------

[](#run-tests)

```
docker compose up -d
docker compose exec -t php vendor/bin/phpunit
```

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance74

Regular maintenance activity

Popularity15

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

9

Last Release

148d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1681915?v=4)[syastrebov](/maintainers/syastrebov)[@syastrebov](https://github.com/syastrebov)

---

Top Contributors

[![syastrebov](https://avatars.githubusercontent.com/u/1681915?v=4)](https://github.com/syastrebov "syastrebov (19 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/syastrebov-circuit-breaker/health.svg)

```
[![Health](https://phpackages.com/badges/syastrebov-circuit-breaker/health.svg)](https://phpackages.com/packages/syastrebov-circuit-breaker)
```

###  Alternatives

[symfony/lock

Creates and manages locks, a mechanism to provide exclusive access to a shared resource

514139.2M692](/packages/symfony-lock)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.7k38.9k](/packages/matomo-matomo)[ecotone/ecotone

Enterprise architecture layer for Laravel and Symfony — CQRS, Event Sourcing, Durable Workflows (Sagas, Orchestrators), Projections, and Outbox messaging via PHP attributes.

564576.7k53](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

751291.4k43](/packages/civicrm-civicrm-core)[illuminate/broadcasting

The Illuminate Broadcasting package.

7127.2M208](/packages/illuminate-broadcasting)[logiscape/mcp-sdk-php

Model Context Protocol SDK for PHP

368116.8k12](/packages/logiscape-mcp-sdk-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
