PHPackages                             jbzoo/retry - 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. jbzoo/retry

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

jbzoo/retry
===========

Tiny PHP library providing retry functionality with multiple backoff strategies and jitter support

7.0.2(9mo ago)975.9k↓25.3%21MITPHPPHP ^8.2CI passing

Since Oct 20Pushed 9mo ago1 watchersCompare

[ Source](https://github.com/JBZoo/Retry)[ Packagist](https://packagist.org/packages/jbzoo/retry)[ RSS](/packages/jbzoo-retry/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (1)Versions (20)Used By (1)

JBZoo / Retry
=============

[](#jbzoo--retry)

[![CI](https://github.com/JBZoo/Retry/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/JBZoo/Retry/actions/workflows/main.yml?query=branch%3Amaster) [![Coverage Status](https://camo.githubusercontent.com/3af7365ad6e54b2cc1a14d1494da16820f9a682b1fe3ff78f499fd06ed13138b/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f4a425a6f6f2f52657472792f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/JBZoo/Retry?branch=master) [![Psalm Coverage](https://camo.githubusercontent.com/738b036cbeda4cc20a7641b258cd13d5c5034195e07cd9bf486bb7ab33f370ce/68747470733a2f2f73686570686572642e6465762f6769746875622f4a425a6f6f2f52657472792f636f7665726167652e737667)](https://shepherd.dev/github/JBZoo/Retry) [![Psalm Level](https://camo.githubusercontent.com/fd113991f6770d1475a4e76ebf3129136cf3da3b970c6d9412c5f9a705b8ecc3/68747470733a2f2f73686570686572642e6465762f6769746875622f4a425a6f6f2f52657472792f6c6576656c2e737667)](https://shepherd.dev/github/JBZoo/Retry) [![CodeFactor](https://camo.githubusercontent.com/1886bc83e20c1d5773bd5c3e22553d4847e52a217c0b19fd46f8e1b0f7558be1/68747470733a2f2f7777772e636f6465666163746f722e696f2f7265706f7369746f72792f6769746875622f6a627a6f6f2f72657472792f6261646765)](https://www.codefactor.io/repository/github/jbzoo/retry/issues)[![Stable Version](https://camo.githubusercontent.com/59200d3dad39988685d7dfc15f61b451ded7eeb2737688f83fb32ff4b9d5c6db/68747470733a2f2f706f7365722e707567782e6f72672f6a627a6f6f2f72657472792f76657273696f6e)](https://packagist.org/packages/jbzoo/retry/) [![Total Downloads](https://camo.githubusercontent.com/e8ab19fb7e893ba6254cb7c1d85fec6cdb137dadcd50b3c9cc6baa9ea8e92c61/68747470733a2f2f706f7365722e707567782e6f72672f6a627a6f6f2f72657472792f646f776e6c6f616473)](https://packagist.org/packages/jbzoo/retry/stats) [![Dependents](https://camo.githubusercontent.com/e141c7a434b0aa7713f51f35ad33264e9b39622308448d8e253251aba7b71397/68747470733a2f2f706f7365722e707567782e6f72672f6a627a6f6f2f72657472792f646570656e64656e7473)](https://packagist.org/packages/jbzoo/retry/dependents?order_by=downloads) [![GitHub License](https://camo.githubusercontent.com/eeefc25cf4cf8e3fda3445f1ea0cc707d14595f3545e8de333e14e26a41a6089/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a627a6f6f2f7265747279)](https://github.com/JBZoo/Retry/blob/master/LICENSE)

Tiny PHP library providing retry functionality with multiple backoff strategies and jitter support.

Features
--------

[](#features)

- **4 retry strategies** (plus the ability to use your own)
- **Optional jitter/randomness** to spread out retries and minimize collisions
- **Wait time cap** to limit maximum retry delays
- **Custom callbacks** for retry logic and error handling
- **Type-safe** with strict typing and comprehensive test coverage
- **Backward compatible** with [stechstudio/backoff](https://github.com/stechstudio/backoff)

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

[](#requirements)

- PHP 8.2 or higher

About This Fork
---------------

[](#about-this-fork)

This library is a modernized fork of [stechstudio/backoff](https://github.com/stechstudio/backoff) with several improvements:

- **Strict typing** and comprehensive test coverage
- **Explicit configuration** instead of global static defaults
- **Better naming** - "retry" terminology instead of "backoff"
- **Enhanced jitter control** with `setJitterPercent()` and `setJitterMinCap()` methods
- **Backward compatibility** through [aliases](./src/aliases.php)

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

[](#installation)

```
composer require jbzoo/retry
```

Quick Start
-----------

[](#quick-start)

This library provides sane defaults for immediate use. By default: quadratic strategy with 100ms base time (`attempt^2 * 100`), maximum 5 retries, and no jitter.

### Simple Function Usage

[](#simple-function-usage)

The simplest way to use Retry is with the `retry` helper function:

```
use function JBZoo\Retry\retry;

$result = retry(function() {
    return doSomeWorkThatMightFail();
});
```

If successful `$result` will contain the result of the closure. If max attempts are exceeded the inner exception is re-thrown.

You can of course provide other options via the helper method if needed.

Parameters: `$callback`, `$maxAttempts`, `$strategy`, `$waitCap`, `$useJitter`.

### Class-Based Usage

[](#class-based-usage)

Constructor parameters: `$maxAttempts`, `$strategy`, `$waitCap`, `$useJitter`.

```
use JBZoo\Retry\Retry;

$retry = new Retry(10, 'exponential', 10000, true);
$result = $retry->run(function() {
    return doSomeWorkThatMightFail();
});
```

### Fluent Interface

[](#fluent-interface)

For dependency injection scenarios, use chainable setters:

```
use JBZoo\Retry\Retry;

$result = (new Retry())
    ->setStrategy('constant')
    ->setMaxAttempts(10)
    ->enableJitter()
    ->run(function() {
        return doSomeWorkThatMightFail();
    });
```

Configuration Philosophy
------------------------

[](#configuration-philosophy)

This library enforces **explicit configuration** over global defaults. Unlike the original library, static configuration variables are deprecated and disabled. This design choice ensures:

- Different parts of your project can have completely different retry settings
- No conflicts with third-party libraries using their own defaults
- Clear, explicit dependency injection patterns

Use dependency injection or direct instantiation instead of global configuration.

Retry Strategies
----------------

[](#retry-strategies)

Four built-in strategies are available, each with a default base time of 100 milliseconds:

### Constant Strategy

[](#constant-strategy)

Sleeps for a fixed time on each retry.

```
use JBZoo\Retry\Strategies\ConstantStrategy;
$strategy = new ConstantStrategy(500); // 500ms each retry
```

### Linear Strategy

[](#linear-strategy)

Sleep time increases linearly: `attempt × baseTime`.

```
use JBZoo\Retry\Strategies\LinearStrategy;
$strategy = new LinearStrategy(200); // 200ms, 400ms, 600ms...
```

### Polynomial Strategy

[](#polynomial-strategy)

Sleep time follows polynomial growth: `(attempt^degree) × baseTime`.

```
use JBZoo\Retry\Strategies\PolynomialStrategy;
$strategy = new PolynomialStrategy(100, 3); // (attempt^3) × 100ms
// Default degree is 2 (quadratic): 100ms, 400ms, 900ms...
```

### Exponential Strategy

[](#exponential-strategy)

Sleep time grows exponentially: `(2^attempt) × baseTime`.

```
use JBZoo\Retry\Strategies\ExponentialStrategy;
$strategy = new ExponentialStrategy(100); // 200ms, 400ms, 800ms...
```

Strategy Usage Options
----------------------

[](#strategy-usage-options)

### String-Based Configuration

[](#string-based-configuration)

```
use JBZoo\Retry\Retry;
use function JBZoo\Retry\retry;

retry(fn() => doWork(), 10, 'constant'); // Uses ConstantStrategy with 100ms default
$retry = new Retry(10, 'constant');
```

### Instance-Based Configuration

[](#instance-based-configuration)

```
use JBZoo\Retry\Retry;
use JBZoo\Retry\Strategies\LinearStrategy;
use function JBZoo\Retry\retry;

retry(fn() => doWork(), 10, new LinearStrategy(500));
$retry = new Retry(10, new LinearStrategy(500));
```

### Integer-Based Configuration

[](#integer-based-configuration)

Passing an integer creates a ConstantStrategy with that base time:

```
retry(fn() => doWork(), 10, 1000); // 1000ms constant delay
$retry = new Retry(10, 1000);
```

### Custom Closure Strategy

[](#custom-closure-strategy)

Define your own strategy with a closure:

```
// Closure receives attempt number and returns sleep time in milliseconds
retry(fn() => doWork(), 10, fn($attempt) => (100 * $attempt) + 5000);

$retry = new Retry(10);
$retry->setStrategy(fn($attempt) => (100 * $attempt) + 5000);
```

Wait Cap
--------

[](#wait-cap)

Limit maximum wait time for fast-growing strategies (like exponential):

```
retry(fn() => doWork(), 10, 'exponential', 5000); // Cap at 5 seconds
$retry = new Retry()->setWaitCap(5000);
```

Jitter
------

[](#jitter)

Prevent retry collisions by adding randomness to wait times. This is crucial when multiple clients might retry simultaneously.

```
retry(fn() => doWork(), 10, 'exponential', null, true); // Enable jitter
$retry = new Retry()->enableJitter();
```

### Advanced Jitter Control

[](#advanced-jitter-control)

Fine-tune jitter behavior with additional methods:

```
$retry = new Retry()
    ->enableJitter()
    ->setJitterPercent(75)    // Use 75% of calculated wait time as max
    ->setJitterMinCap(100);   // Minimum jitter time of 100ms
```

By default, this library uses "FullJitter" - a random time between 0 and the calculated wait time. See [AWS's excellent explanation](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) for more details.

Advanced Usage
--------------

[](#advanced-usage)

### Custom Retry Logic

[](#custom-retry-logic)

Implement custom retry conditions beyond simple exception handling:

```
use JBZoo\Retry\Retry;

$retry = new Retry();
$retry->setDecider(function($attempt, $maxAttempts, $result, $exception = null) {
    // Custom logic: retry based on time, specific exceptions, return values, etc.
    return $attempt < 3 && ($exception instanceof SpecificException);
});
```

### Error Handling

[](#error-handling)

Add logging or monitoring for retry attempts:

```
use JBZoo\Retry\Retry;

$retry = new Retry();
$retry->setErrorHandler(function($exception, $attempt, $maxAttempts) {
    error_log("Retry {$attempt}/{$maxAttempts}: {$exception->getMessage()}");
});
```

Development
-----------

[](#development)

### Running Tests

[](#running-tests)

```
make update    # Install dependencies
make test      # Run PHPUnit tests
make codestyle # Run code quality checks
make test-all  # Run both tests and code style
```

License
-------

[](#license)

MIT

See Also
--------

[](#see-also)

- [CI-Report-Converter](https://github.com/JBZoo/CI-Report-Converter) - Converting different error reports for deep compatibility with popular CI systems.
- [Composer-Diff](https://github.com/JBZoo/Composer-Diff) - See what packages have changed after `composer update`.
- [Composer-Graph](https://github.com/JBZoo/Composer-Graph) - Dependency graph visualization of composer.json based on mermaid-js.
- [Mermaid-PHP](https://github.com/JBZoo/Mermaid-PHP) - Generate diagrams and flowcharts with the help of the mermaid script language.
- [Utils](https://github.com/JBZoo/Utils) - Collection of useful PHP functions, mini-classes, and snippets for every day.
- [Image](https://github.com/JBZoo/Image) - Package provides object-oriented way to manipulate with images as simple as possible.
- [Data](https://github.com/JBZoo/Data) - Extended implementation of ArrayObject. Use files as config/array.
- [SimpleTypes](https://github.com/JBZoo/SimpleTypes) - Converting any values and measures - money, weight, exchange rates, length, ...

###  Health Score

54

—

FairBetter than 96% of packages

Maintenance58

Moderate activity, may be stable

Popularity37

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 56.9% 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 ~181 days

Recently: every ~355 days

Total

19

Last Release

279d ago

Major Versions

0.4 → 1.0.02018-06-05

1.2 → 2.0.02021-03-18

2.2.2 → 3.0.02022-06-06

3.0.0 → 7.0.02023-07-09

PHP version history (4 changes)2.0.0PHP &gt;=7.2

3.0.0PHP &gt;=7.4

7.0.0PHP ^8.1

7.0.2PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/75e6de2785f6d099699f430ff58404af4fc0e83060d2953028c9664a54704a5f?d=identicon)[smetdenis](/maintainers/smetdenis)

---

Top Contributors

[![SmetDenis](https://avatars.githubusercontent.com/u/1118678?v=4)](https://github.com/SmetDenis "SmetDenis (41 commits)")[![jszobody](https://avatars.githubusercontent.com/u/203749?v=4)](https://github.com/jszobody "jszobody (24 commits)")[![Lewiscowles1986](https://avatars.githubusercontent.com/u/2605791?v=4)](https://github.com/Lewiscowles1986 "Lewiscowles1986 (2 commits)")[![bubba-h57](https://avatars.githubusercontent.com/u/603630?v=4)](https://github.com/bubba-h57 "bubba-h57 (2 commits)")[![dbellettini](https://avatars.githubusercontent.com/u/325358?v=4)](https://github.com/dbellettini "dbellettini (1 commits)")[![askurihin](https://avatars.githubusercontent.com/u/37978981?v=4)](https://github.com/askurihin "askurihin (1 commits)")[![kler](https://avatars.githubusercontent.com/u/966132?v=4)](https://github.com/kler "kler (1 commits)")

---

Tags

back-offbackofffailurejbzoojittermiddlewarerestartrestarterretryretry-aftermiddlewareretryback-offretry-afterJitterbackoffrestartretryablefailurejbzoo

### Embed Badge

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

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

###  Alternatives

[eventsauce/backoff

Back-off strategy interface

70848.9k8](/packages/eventsauce-backoff)[caseyamcl/guzzle_retry_middleware

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

21912.2M77](/packages/caseyamcl-guzzle-retry-middleware)[league/uri-components

URI components manipulation library

31940.5M98](/packages/league-uri-components)[tobion/retry

A generic library to retry an operation in case of an error. You can configure the behavior like the exceptions to retry on.

16480.3k](/packages/tobion-retry)[yriveiro/php-backoff

Simple backoff / retry functionality

2780.9k1](/packages/yriveiro-php-backoff)[bryanjhv/slim-session

Session middleware and helper for Slim framework 4.

2411.0M16](/packages/bryanjhv-slim-session)

PHPackages © 2026

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