PHPackages                             diephp/perhaps - 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. diephp/perhaps

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

diephp/perhaps
==============

Catch and Retry Code Execution

v1.0.3(1y ago)11.2kMITPHPPHP ^7.4 || ^8.0

Since May 24Pushed 1y ago1 watchersCompare

[ Source](https://github.com/diephp/perhaps)[ Packagist](https://packagist.org/packages/diephp/perhaps)[ RSS](/packages/diephp-perhaps/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (5)Used By (0)

[![Total Downloads](https://camo.githubusercontent.com/f30cd7f8ddcca0ccf347a97dfd81a1100497ad44550ef49068fdfc06eaa76a1c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6469657068702f70657268617073)](https://packagist.org/packages/diephp/perhaps)[![Latest Stable Version](https://camo.githubusercontent.com/ca17e6985f15c35d0a89ee6ab7c95601a86089002d1b6faf9f2c3b28c9d55b6a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6469657068702f70657268617073)](https://packagist.org/packages/diephp/perhaps)[![License](https://camo.githubusercontent.com/306e9a338cf9d5503fe3a34aa11930bb881792851483342a3b1a1ba7bb3d3a3a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6469657068702f70657268617073)](https://packagist.org/packages/diephp/perhaps)

Perhaps Retry Library
=====================

[](#perhaps-retry-library)

A Laravel package that provides a simple way to retry any logic with customizable attempts and delays. This can be particularly useful in scenarios where certain operations might fail due to transient issues, such as network errors or temporary service outages.

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

[](#installation)

1. Install the package via Composer:

    ```
    composer require diephp/perhaps
    ```
2. Register the service provider in your `config/app.php` file:

    ```
    'providers' => [
        // ...
        \DiePHP\Perhaps\Providers\PerhapsServiceProvider::class,
    ],
    ```

    or for laravel 11+ add Provider to list in bootstrap/providers.php

    ```
    return [
        App\Providers\AppServiceProvider::class,
        ...
        \DiePHP\Perhaps\Providers\PerhapsServiceProvider::class,
    ];
    ```
3. Optionally, publish the package configuration:

    ```
    php artisan vendor:publish --tag=perhaps
    ```

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

The main function provided by this package is `Perhaps::retry`. You can use it to retry any logic with a specified number of attempts.

```
use DiePHP\Perhaps\Facades\Perhaps;

Perhaps::retry(function() {
    // Your logic here
}, 3); // Retry 3 times
```

### Handling Delays

[](#handling-delays)

You can also specify a delay sequence using a `Traversable` iterator. This allows you to define custom delay logic between retries. you can see details on

LogarithmicSequence
-------------------

[](#logarithmicsequence)

```
use DiePHP\Perhaps\Facades\Perhaps;
use DiePHP\Sequences\LogarithmicSequence;

Perhaps::retry(function() {
    // Your logic here
}, 10, new LogarithmicSequence(1000000, 100)); // Retry 10 times with logarithmicSequence delay
```

### Simple Explanation:

[](#simple-explanation)

Each value in the sequence is derived from multiplying the previous value by a logarithmic growth factor, which depends on the configured percentage. Squaring the factor introduces a faster scaling effect, and rounding ensures integer progression. The **result on the 10th iteration** will exceed **3 hours**, which means that by this point, the total time represented by the sequence will have grown significantly. This feature of the `LogarithmicSequence` can be quite useful when working with remote services that may become temporarily unavailable. In such cases:

- You may not want to **abandon already processed data**, especially if its collection or processing took a considerable effort.
- Instead, the logarithmic growth helps you **wait longer between retries**, which increases the likelihood of success without wasting too much CPU time or bandwidth in continual attempts.

This makes it possible to gracefully handle **delays** and **resilience** in long-running processes when interacting with unreliable external services.

### Retry result table by LogarithmicSequence(1000000, 100)

[](#retry-result-table-by-logarithmicsequence1000000-100)

**Microseconds****Seconds****Minutes****Hours**1,000,00010.020.00032,866,7482.870.0480.00088,218,2438.220.1370.002323,559,62723.560.3930.006567,539,49967.541.1260.0188193,618,682193.623.2270.0538555,055,849555.069.2510.15421,591,204,8991,591.2026.5200.44204,561,582,4684,561.5876.0261.267113,076,904,56713,076.90217.9483.6325ProgressiveSequence
-------------------

[](#progressivesequence)

```
use DiePHP\Perhaps\Facades\Perhaps;
use DiePHP\Sequences\ProgressiveSequence;

Perhaps::retry(function() {
    // Your logic here
}, 20, new ProgressiveSequence(1000000, 100)); // Retry 10 times with progressive delay
```

### **How `ProgressiveSequence` works (in words)**:

[](#how-progressivesequence-works-in-words)

The `ProgressiveSequence` is a number sequence generator where each value grows progressively based on a fixed starting value and a percentage increment.

1. **Starting Value**: The sequence starts with a given base value (`start`).
2. **Growth By Percentage**: For each iteration:

    - The increment is calculated as a percentage of the starting value (`start`).
    - This percentage-based increment grows proportionally with the iteration number, meaning each next value adds **more** than the previous iteration.
3. **Round Calculation**: The calculated result is rounded to the nearest integer to avoid fractional values.
4. **Behavior Over Iterations**: Since the increment grows with each step, the sequence becomes larger and larger — forming a **progressive growth trend**.

### **Key Difference from `LogarithmicSequence`**:

[](#key-difference-from-logarithmicsequence)

While `LogarithmicSequence` grows based on a logarithmic scaling factor, which slows down over time, the `ProgressiveSequence` grows linearly and **increases consistently** by a calculated percentage.

### **Microseconds Conversion Table**

[](#microseconds-conversion-table)

Here’s the conversion of the provided microseconds values into seconds, minutes, and hours as requested:

**Microseconds****Seconds****Minutes****Hours**1,000,00010.020.00032,000,00020.030.00064,000,00040.070.00117,000,00070.120.001911,000,000110.180.003116,000,000160.270.004422,000,000220.370.006129,000,000290.480.008137,000,000370.620.010346,000,000460.770.012856,000,000560.930.015667,000,000671.120.018679,000,000791.320.022092,000,000921.530.0255106,000,0001061.770.0294121,000,0001212.020.0336137,000,0001372.280.0380154,000,0001542.570.0428172,000,0001722.870.0478191,000,0001913.180.0531RandSequence
------------

[](#randsequence)

```
use DiePHP\Perhaps\Facades\Perhaps;
use DiePHP\Sequences\RandSequence;

Perhaps::retry(function() {
    // Your logic here
}, 10, new RandSequence(1000000, 90000000));
```

**Microseconds****Seconds****Minutes****Hours**2,000,0002.000.030.000682,904,22382.901.380.02338,693,29838.690.640.010832,757,67332.760.550.009115,554,54815.550.260.004321,913,92321.910.370.006156,585,79856.590.940.015731,320,17331.320.520.008725,867,04825.870.430.00725,976,4235.980.100.0017ExponentialSequence
-------------------

[](#exponentialsequence)

```
use DiePHP\Perhaps\Facades\Perhaps;
use DiePHP\Sequences\ExponentialSequence;

Perhaps::retry(function() {
    // Your logic here
}, 10, new ExponentialSequence(10, 100));
```

- **Exponential Growth**: Unlike linear or logarithmic sequences, this formula ensures that the numbers grow at an increasingly rapid pace. Each iteration introduces a massively larger value than the previous one.
- **Practical Usage**: Such sequences are most often used in scenarios where values need to expand exponentially, such as in backoff strategies or modeling growth over time.

**Microseconds****Seconds****Minutes****Hours**100.000010.000000170.000000003200.000020.000000330.0000000064000.00040.000006670.0000001118,0000.0080.000133330.00000222160,0000.160.002670.00004443,200,0003.20.053330.0008964,000,00064.001.066670.017781,280,000,0001,280.0021.330.3555625,600,000,00025,600.00426.677.1111512,000,000,000512,000.008,533.33142.222Example with Exception Handling
===============================

[](#example-with-exception-handling)

In this example, the retry logic will handle exceptions and log the retry attempts.

```
Perhaps::retry(function($attempt) {
    if ($attempt < 3) {
        throw new \Exception("Simulated failure");
    }
    // Successful operation
    echo "Success on attempt $attempt";
}, 5); // Retry 5 times
```

---

```
Perhaps::retry(function () use ($data) {
    History::create($data); // example
}, 3, new LogarithmicSequence(1000000, 70));
```

Configuration
-------------

[](#configuration)

You can configure the package by modifying the published configuration file `config/perhaps.php`. This allows you to customize the logging and exception handling behavior.

License
-------

[](#license)

This package is open-source software licensed under the [MIT license](LICENSE).

### Key Points

[](#key-points)

- The `retry` method allows you to retry any callable logic a specified number of times.
- You can specify a delay sequence for custom delay logic between retries.
- Register the service provider and optionally publish the configuration for customization.
- Use the provided facade for easy access to the `retry` method in your Laravel application.

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance43

Moderate activity, may be stable

Popularity19

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity49

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 ~90 days

Total

4

Last Release

452d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/843845c3857f227042e7ae4ea3f5e255f8e14fc59d6a971b72bc0670996e7701?d=identicon)[diephp](/maintainers/diephp)

---

Top Contributors

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

---

Tags

retrycatch

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/diephp-perhaps/health.svg)

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

###  Alternatives

[vkartaviy/retry

The library for repeatable and retryable operations

29227.2k2](/packages/vkartaviy-retry)[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.

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

Simple backoff / retry functionality

2675.1k1](/packages/yriveiro-php-backoff)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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