PHPackages                             philiprehberger/php-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. philiprehberger/php-circuit-breaker

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

philiprehberger/php-circuit-breaker
===================================

Circuit breaker pattern with configurable thresholds and multiple storage backends

v1.3.0(4mo ago)168MITPHPPHP ^8.2CI passing

Since Mar 15Pushed 2mo agoCompare

[ Source](https://github.com/philiprehberger/php-circuit-breaker)[ Packagist](https://packagist.org/packages/philiprehberger/php-circuit-breaker)[ Docs](https://github.com/philiprehberger/php-circuit-breaker)[ GitHub Sponsors](https://github.com/philiprehberger)[ RSS](/packages/philiprehberger-php-circuit-breaker/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (6)Versions (9)Used By (0)

PHP Circuit Breaker
===================

[](#php-circuit-breaker)

[![Tests](https://github.com/philiprehberger/php-circuit-breaker/actions/workflows/tests.yml/badge.svg)](https://github.com/philiprehberger/php-circuit-breaker/actions/workflows/tests.yml)[![Latest Version on Packagist](https://camo.githubusercontent.com/baf5f4f66f63d3672cafd0ec125b46a673fd54f8b0ace37c689334fefc1ac542/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7068696c69707265686265726765722f7068702d636972637569742d627265616b65722e737667)](https://packagist.org/packages/philiprehberger/php-circuit-breaker)[![Last updated](https://camo.githubusercontent.com/9ddc07862963655b8a25795ccdc14c2ec7752cbc97166d981827016c42b778f2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f7068696c69707265686265726765722f7068702d636972637569742d627265616b6572)](https://github.com/philiprehberger/php-circuit-breaker/commits/main)

Circuit breaker pattern with configurable thresholds and multiple storage backends.

Requirements
------------

[](#requirements)

- PHP 8.2+

Installation
------------

[](#installation)

```
composer require philiprehberger/php-circuit-breaker
```

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

```
use PhilipRehberger\CircuitBreaker\CircuitBreaker;
use PhilipRehberger\CircuitBreaker\CircuitConfig;
use PhilipRehberger\CircuitBreaker\Storage\InMemoryStorage;

$breaker = new CircuitBreaker(
    service: 'payment-api',
    config: new CircuitConfig(
        failureThreshold: 5,
        recoveryTimeout: 30,
        successThreshold: 1,
    ),
    storage: new InMemoryStorage(),
);

$result = $breaker->call(function () {
    return file_get_contents('https://api.example.com/charge');
});
```

### Fluent Builder

[](#fluent-builder)

```
use PhilipRehberger\CircuitBreaker\CircuitBreaker;
use PhilipRehberger\CircuitBreaker\Storage\FileStorage;

$breaker = CircuitBreaker::for('payment-api')
    ->failAfter(3)
    ->recoverAfter(60)
    ->storage(new FileStorage('/tmp/circuits'))
    ->onStateChange(function ($event, $breaker) {
        echo "Circuit event: {$event->value}\n";
    })
    ->build();

try {
    $result = $breaker->call(fn () => callExternalService());
} catch (\PhilipRehberger\CircuitBreaker\CircuitOpenException $e) {
    // Circuit is open, use fallback
}
```

### Per-Key Circuit Breakers

[](#per-key-circuit-breakers)

Use `KeyedCircuitBreaker` to manage independent circuit breakers per key:

```
use PhilipRehberger\CircuitBreaker\KeyedCircuitBreaker;
use PhilipRehberger\CircuitBreaker\CircuitConfig;
use PhilipRehberger\CircuitBreaker\Storage\InMemoryStorage;

$breakers = new KeyedCircuitBreaker(
    config: new CircuitConfig(failureThreshold: 3, recoveryTimeout: 60),
    storage: new InMemoryStorage(),
);

$userResult  = $breakers->call('user-api',  fn () => fetchUsers());
$orderResult = $breakers->call('order-api', fn () => fetchOrders());
```

### Fallback

[](#fallback)

Register a fallback to return a default value when the circuit is open instead of throwing:

```
$breaker = CircuitBreaker::for('payment-api')
    ->failAfter(3)
    ->recoverAfter(60)
    ->fallback(fn () => ['status' => 'unavailable'])
    ->build();

// Returns the fallback value when the circuit is open
$result = $breaker->call(fn () => callExternalService());
```

### Health Check Probes

[](#health-check-probes)

Register a health check probe for smarter recovery from the Open state:

```
$breaker = new CircuitBreaker(
    service: 'payment-api',
    config: new CircuitConfig(failureThreshold: 3, recoveryTimeout: 30),
);

$breaker->setHealthCheck(function (): bool {
    // Check if the external service is reachable
    return @file_get_contents('https://api.example.com/health') !== false;
});
```

When the recovery timeout elapses, the health check runs before transitioning to HalfOpen. If the probe fails, the recovery timer resets.

### Metrics

[](#metrics)

Inspect detailed metrics about circuit breaker usage:

```
$breaker = new CircuitBreaker('payment-api');

$breaker->call(fn () => fetchData());

$metrics = $breaker->metrics();
// [
//     'total_calls'          => 1,
//     'successful_calls'     => 1,
//     'failed_calls'         => 0,
//     'success_rate'         => 1.0,
//     'current_state'        => 'closed',
//     'state_changed_at'     => null,
//     'consecutive_failures' => 0,
// ]
```

### Stats

[](#stats)

Inspect circuit breaker usage statistics at any time:

```
$breaker = new CircuitBreaker('payment-api');

$breaker->call(fn () => fetchData());

$stats = $breaker->getStats();
// [
//     'total_calls'     => 1,
//     'successes'       => 1,
//     'failures'        => 0,
//     'last_failure_at' => null,
//     'current_state'   => 'closed',
// ]
```

### Custom Storage Backend

[](#custom-storage-backend)

```
use PhilipRehberger\CircuitBreaker\Contracts\Storage;
use PhilipRehberger\CircuitBreaker\CircuitState;

class RedisStorage implements Storage
{
    public function getState(string $service): CircuitState { /* ... */ }
    public function setState(string $service, CircuitState $state): void { /* ... */ }
    public function incrementFailures(string $service): int { /* ... */ }
    public function resetFailures(string $service): void { /* ... */ }
    public function getFailureCount(string $service): int { /* ... */ }
    public function getLastFailureTime(string $service): ?float { /* ... */ }
    public function setLastFailureTime(string $service, float $time): void { /* ... */ }
}
```

API
---

[](#api)

### CircuitBreaker

[](#circuitbreaker)

MethodDescription`new CircuitBreaker(string $service, CircuitConfig $config, Storage $storage)`Create a circuit breaker`CircuitBreaker::for(string $service)`Create a fluent builder`->call(callable $fn): mixed`Execute a callable through the circuit breaker`->isOpen(): bool`Check if the circuit is open`->isClosed(): bool`Check if the circuit is closed`->isHalfOpen(): bool`Check if the circuit is half-open`->state(): CircuitState`Get the current circuit state`->reset(): void`Reset the circuit to closed`->trip(): void`Manually open the circuit`->getStats(): array`Get usage statistics (total calls, successes, failures, last failure timestamp, current state)`->metrics(): array`Get detailed metrics (total, successful, failed calls, success rate, state, state change time, consecutive failures)`->setFallback(callable $fallback): void`Register a fallback invoked when the circuit is open`->setHealthCheck(callable $probe): self`Register a health check probe for smarter Open-to-HalfOpen recovery### CircuitBreakerBuilder

[](#circuitbreakerbuilder)

MethodDescription`->failAfter(int $failures): self`Set the failure threshold`->recoverAfter(int $seconds): self`Set the recovery timeout`->succeedAfter(int $successes): self`Set the success threshold for half-open`->timeout(float $seconds): self`Set the call timeout`->storage(Storage $storage): self`Set the storage backend`->fallback(callable $fallback): self`Register a fallback for when the circuit is open`->onStateChange(callable $callback): self`Set a state change callback`->build(): CircuitBreaker`Build the configured instance### KeyedCircuitBreaker

[](#keyedcircuitbreaker)

MethodDescription`new KeyedCircuitBreaker(CircuitConfig $config, Storage $storage)`Create a keyed circuit breaker manager`->call(string $key, callable $fn): mixed`Execute through the breaker for the given key`->state(string $key): CircuitState`Get the state for a specific key`->isOpen(string $key): bool`Check if the circuit for a key is open`->isClosed(string $key): bool`Check if the circuit for a key is closed`->isHalfOpen(string $key): bool`Check if the circuit for a key is half-open`->reset(string $key): void`Reset the circuit for a specific key`->trip(string $key): void`Manually open the circuit for a specific key`->remove(string $key): void`Remove the breaker for a key entirely`->keys(): string[]`Get all tracked keys`->count(): int`Get the number of tracked keys### CircuitConfig

[](#circuitconfig)

ParameterTypeDefaultDescription`failureThreshold``int``5`Failures before opening`recoveryTimeout``int``30`Seconds before half-open transition`successThreshold``int``1`Successes in half-open to close`timeout``?float``null`Optional call timeout in seconds### Storage Backends

[](#storage-backends)

ClassDescription`InMemoryStorage`In-memory, scoped to the current process`FileStorage`JSON file-based, persists across requests`SlidingWindowStorage`Time-window-based failure tracking with automatic pruningDevelopment
-----------

[](#development)

```
composer install
vendor/bin/phpunit
vendor/bin/pint --test
```

Support
-------

[](#support)

If you find this project useful:

⭐ [Star the repo](https://github.com/philiprehberger/php-circuit-breaker)

🐛 [Report issues](https://github.com/philiprehberger/php-circuit-breaker/issues?q=is%3Aissue+is%3Aopen+label%3Abug)

💡 [Suggest features](https://github.com/philiprehberger/php-circuit-breaker/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement)

❤️ [Sponsor development](https://github.com/sponsors/philiprehberger)

🌐 [All Open Source Projects](https://philiprehberger.com/open-source-packages)

💻 [GitHub Profile](https://github.com/philiprehberger)

🔗 [LinkedIn Profile](https://www.linkedin.com/in/philiprehberger)

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance80

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

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

8

Last Release

136d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cfd7d24cbbf32400fa13ce0bbe7a31edd2d66a6d4488eafdb3d64c5337bf0435?d=identicon)[philiprehberger](/maintainers/philiprehberger)

---

Top Contributors

[![philiprehberger](https://avatars.githubusercontent.com/u/8218077?v=4)](https://github.com/philiprehberger "philiprehberger (14 commits)")

---

Tags

phpretrycircuit breakerfault toleranceresilience

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[gabrielanhaia/laravel-circuit-breaker

Laravel integration for PHP Circuit Breaker — multiple storage drivers, middleware, Artisan commands, and event system

492.3k](/packages/gabrielanhaia-laravel-circuit-breaker)

PHPackages © 2026

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