PHPackages                             guzzlehttp/retry-subscriber - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. guzzlehttp/retry-subscriber

AbandonedArchivedLibrary[HTTP &amp; Networking](/categories/http)

guzzlehttp/retry-subscriber
===========================

Retries failed HTTP requests using customizable retry strategies (Guzzle 4+)

2.0.2(11y ago)61976.8k↓26.4%1620MITPHPPHP &gt;=5.4.0

Since Mar 16Pushed 9y ago5 watchersCompare

[ Source](https://github.com/guzzle/retry-subscriber)[ Packagist](https://packagist.org/packages/guzzlehttp/retry-subscriber)[ Docs](http://guzzlephp.org/)[ RSS](/packages/guzzlehttp-retry-subscriber/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (9)Used By (20)

Guzzle Retry Subscriber
=======================

[](#guzzle-retry-subscriber)

Retries failed HTTP requests using customizable retry strategies.

Here's a simple example of how it's used:

```
use GuzzleHttp\Subscriber\Retry\RetrySubscriber;

// Retry 500 and 503 responses
$retry = new RetrySubscriber([
    'filter' => RetrySubscriber::createStatusFilter()
]);

$client = new GuzzleHttp\Client();
$client->getEmitter()->attach($retry);
```

Installing
----------

[](#installing)

Add the following to your composer.json:

```
{
    "require": {
        "guzzlehttp/retry-subscriber": "~2.0"
    }
}
```

Creating a RetrySubscriber
--------------------------

[](#creating-a-retrysubscriber)

The constructor of the RetrySubscriber accepts an associative array of configuration options:

filter(callable) (Required) Filter used to determine whether or not to retry a request. The filter must be a callable that accepts the current number of retries as the first argument and a `GuzzleHttp\Event\AbstractTransferEvent` object as the second argument. The filter must return `true` or `false` to denote if the request must be retried.delayCallable that accepts the number of retries as the first argument and a `GuzzleHttp\Event\AbstractTransferEvent` as the second argument. The callable must return the amount of of time (in milliseconds) to delay.

If no `delay` configuration value is provided, then a default exponential backoff implementation is used.

maxInteger representing the maximum number of retries to allow before giving up.

If no `max` configuration value is provided, then a request will be retried 5 times.

Determining what should be retried
----------------------------------

[](#determining-what-should-be-retried)

The required `filter` option of the RetrySubscriber's constructor is a callable that is invoked to determine if a request should be retried.

When the filter is invoked, it is provided the current retry count for the request and a `GuzzleHttp\Event\CompleteEvent` or `GuzzleHttp\Event\ErrorEvent` (both events extend from `GuzzleHttp\Event\AbstractTransferEvent`, so you should typehint on that). The filter must then return true if the request should be retried, or false if it should not be retried.

Here's an example of retrying failed 500 responses sent to the `/foo`endpoint:

```
use GuzzleHttp\Event\AbstractTransferEvent;
use GuzzleHttp\Subscriber\Retry\RetrySubscriber;

$retry = new RetrySubscriber([
    'filter' => function ($retries, AbstractTransferEvent $event) {
        $resource = $event->getRequest()->getResource();
        // A response is not always received (e.g., for timeouts)
        $code = $event->getResponse()
            ? $event->getResponse()->getStatusCode()
            : null;

        return $resource == '/foo' && $code == 500;
    }
]);

$client = new GuzzleHttp\Client();
$client->getEmitter()->attach($retry);
```

### Filter Chains

[](#filter-chains)

You can create more customizable retry logic with filter chains, which are created using the static `RetrySubscriber::createChainFilter()` method. This method accepts an array of callable filters that are each invoked one after the other. The filters in the chain should return one of the following values, which affects how the rest of the chain is executed.

- `RetrySubscriber::RETRY` (i.e., `true`) – Retry the request.
- `RetrySubscriber::DEFER` (i.e., `false`) – Defer to the next filter in the chain.
- `RetrySubscriber::BREAK_CHAIN` (i.e., `-1`) – Stop the filter chain, and do **not** retry the request.

Here's an example using filter chains that retries failed 500 and 503 responses for only idempotent or "safe" requests as defined by [RFC 7231](http://tools.ietf.org/html/rfc7231#section-4.2.2).

```
use GuzzleHttp\Event\AbstractTransferEvent;
use GuzzleHttp\Subscriber\Retry\RetrySubscriber;

// Retry 500 and 503 responses that were sent as GET and HEAD requests.
$filter = RetrySubscriber::createChainFilter([
    // Does early filter to force non-idempotent methods to NOT be retried.
    RetrySubscriber::createIdempotentFilter(),
    // Performs the last check, returning ``true`` or ``false`` based on
    // if the response received a 500 or 503 status code.
    RetrySubscriber::createStatusFilter([500, 503])
]);

$retry = new RetrySubscriber(['filter' => $filter]);
$client = new GuzzleHttp\Client();
$client->getEmitter()->attach($retry);
```

Customizing the amount of delay
-------------------------------

[](#customizing-the-amount-of-delay)

`delay` is an optional configuration option in the RetrySubscriber's constructor that is a callable used to determine the amount of time to delay before retrying a request that has been marked as needing a retry. The callable accepts the current number of retries and either a `GuzzleHttp\Event\CompleteEvent` or a `GuzzleHttp\Event\ErrorEvent`. The function must then return an integer or float representing the amount of time in milliseconds to sleep.

Note

Omitting this argument will use a default exponential backoff strategy.

Here's an example of creating a custom delay that always delays for 1 millisecond:

```
use GuzzleHttp\Subscriber\Retry\RetrySubscriber;

$retry = new RetrySubscriber([
    'filter' => RetrySubscriber::createStatusFilter(),
    'delay'  => function ($number, $event) { return 1; }
]);
```

Changing the max number of retries
----------------------------------

[](#changing-the-max-number-of-retries)

You can also specify an optional max number of retries in the `max`configuration option of the RetrySubscriber's constructor. If not specified, a request can be retried up to 5 times before it is allowed to fail.

```
use GuzzleHttp\Subscriber\Retry\RetrySubscriber;

$retry = new RetrySubscriber([
    'filter' => RetrySubscriber::createStatusFilter(),
    'max'    => 3
]);
```

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity50

Moderate usage in the ecosystem

Community30

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 83.3% 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 ~46 days

Total

7

Last Release

4168d ago

Major Versions

0.1.2 → 1.0.02014-08-04

1.0.0 → 2.0.02014-10-13

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/190930?v=4)[Michael Dowling](/maintainers/mtdowling)[@mtdowling](https://github.com/mtdowling)

---

Top Contributors

[![mtdowling](https://avatars.githubusercontent.com/u/190930?v=4)](https://github.com/mtdowling "mtdowling (50 commits)")[![GrahamCampbell](https://avatars.githubusercontent.com/u/2829600?v=4)](https://github.com/GrahamCampbell "GrahamCampbell (5 commits)")[![jeremeamia](https://avatars.githubusercontent.com/u/107867?v=4)](https://github.com/jeremeamia "jeremeamia (2 commits)")[![ecoleman](https://avatars.githubusercontent.com/u/1598?v=4)](https://github.com/ecoleman "ecoleman (1 commits)")[![luxifer](https://avatars.githubusercontent.com/u/419078?v=4)](https://github.com/luxifer "luxifer (1 commits)")[![SergeyTsalkov](https://avatars.githubusercontent.com/u/3589642?v=4)](https://github.com/SergeyTsalkov "SergeyTsalkov (1 commits)")

---

Tags

httpGuzzleretry

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/guzzlehttp-retry-subscriber/health.svg)

```
[![Health](https://phpackages.com/badges/guzzlehttp-retry-subscriber/health.svg)](https://phpackages.com/packages/guzzlehttp-retry-subscriber)
```

###  Alternatives

[kitetail/zttp

A developer-experience focused HTTP client, optimized for most common use cases.

1.7k1.2M72](/packages/kitetail-zttp)[kevinrob/guzzle-cache-middleware

A HTTP/1.1 Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack. (RFC 7234)

43117.4M104](/packages/kevinrob-guzzle-cache-middleware)[caseyamcl/guzzle_retry_middleware

Guzzle v6+ retry middleware that handles 429/503 status codes and connection timeouts

21610.7M64](/packages/caseyamcl-guzzle-retry-middleware)[php-http/guzzle7-adapter

Guzzle 7 HTTP Adapter

9057.1M555](/packages/php-http-guzzle7-adapter)[graham-campbell/guzzle-factory

Provides A Simple Guzzle Factory With Good Defaults

916.4M49](/packages/graham-campbell-guzzle-factory)[rtheunissen/guzzle-log-middleware

Guzzle middleware to log requests and responses

842.3M17](/packages/rtheunissen-guzzle-log-middleware)

PHPackages © 2026

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