PHPackages                             n-hor/pcntl-parallel - 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. n-hor/pcntl-parallel

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

n-hor/pcntl-parallel
====================

Execute PHP code in parallel with single or persistent task worker.

1.0(1y ago)283932[1 PRs](https://github.com/n-hor/pcntl-parallel/pulls)MITPHPPHP ^8.1

Since Oct 16Pushed 1y ago1 watchersCompare

[ Source](https://github.com/n-hor/pcntl-parallel)[ Packagist](https://packagist.org/packages/n-hor/pcntl-parallel)[ RSS](/packages/n-hor-pcntl-parallel/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (2)Versions (4)Used By (0)

Simple solution for running PHP code concurrently
=================================================

[](#simple-solution-for-running-php-code-concurrently)

This package for running code in parallel and creating a pool of processes to execute various tasks (like queue workers).

Improve performance of your php app with this package!

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

[](#installation)

```
composer require n-hor/pcntl-parallel
```

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

[](#requirements)

- PHP &gt;= 8.1
- ext-sockets
- ext-pcntl
- posix (optional)

Usage
-----

[](#usage)

### SingleTaskWorker

[](#singletaskworker)

Usage of `SingleTaskWorker`:

```
use NHor\PcntlParallel\SingleTaskWorker;

$worker1 = (new SingleTaskWorker())
        ->setCallback(fn () => DB::insert(...))
        ->run();

$worker2 =  (new SingleTaskWorker())
        ->setCallback(fn () => DB::update(...))
        ->run();

// do something immediately
//...your code...
// or you can wait for the result of each worker
$resultWorker1 = $worker1->waitOutput(),
$resultWorker2 = $worker2->waitOutput(),
```

If an exception occurs in a parallel process, Worker returns `WorkerExceptionMessage` as output. Example With timeout exception:

```
use NHor\PcntlParallel\SingleTaskWorker;

//
$worker = (new SingleTaskWorker())
            //max execution time in seconds
            ->setTimeout(3)
            ->setCallback(fn () => YourLongTimeJob::run(...))
            ->run();

$result = $worker->waitOutput();

if($result instanceof WorkerExceptionMessage) {
  //check and handle errors from worker
}
```

You could use wrapper of `SingleTaskWorker` for running multiple single workers:

```
use NHor\PcntlParallel\ParallelTasks;

$parallelTasks = ParallelTasks::add([
        function () {
            sleep(1);
            return time();
        },
        function () {
            sleep(1);
            return time();
        },
        function () {
            sleep(2);
            return time();
        },
        function () {
            sleep(2);
            return time();
        },
    ])
    // common callback that is executed after a fork in child processes,
    // such as reconnecting to services to avoid errors after a fork.
    ->setCommonBeforeExecutionCallback(function () {
          DB::reconnect();
          Redis::reconnect();
    })
    ->run();

// do something immediately
//...your code...

//You can wait for all tasks to complete and specify a sleep timeout in microseconds while waiting for output.
$result = $parallelTasks->waitOutput(sleepTimeout: 100, waitTimeout: 1_000_000);

$result[0] === $result[1]; //true
$result[2] === $result[3]; //true
```

You can wait for only a specific task to complete:

```
use NHor\PcntlParallel\ParallelTasks;

$parallelTasks = ParallelTasks::add([
        fn() => 'task1',
        fn() => 'task2',
        fn() => 'task3',

    ])
    ->run();

//get tasks workers
[$task1, $task2, $task3] = $parallelTasks->getTaskWorkers();

$result = $task2->waitOutput(); //task2

//Or you can just check if there is a result without blocking the program
$task1Output = $task1->getOutput();

if ($task1Output !== Channel::NO_CONTENT) {
    //task done
}
```

Example of running with concurrency limitation:

```
use NHor\PcntlParallel\ParallelTasks;
use NHor\PcntlParallel\Messages\WorkerExceptionMessage;

$result = ParallelTasks::add([
    fn () => time(),
    fn () => time(),
    function () {
        sleep(2);
        return time();
    },
    fn () => time(),
])
    //set max execution time in seconds for each worker
    ->setTimeout(1)
    //at the same time only 2 parallel process is running
    //this method wait when all process is complete.
    ->runWithProcessLimitation(2);

//WorkerExceptionMessage since third task is sleep 2 seconds but timeout is 1 second.
$result[2] instanceof WorkerExceptionMessage; //true
```

`PersistenceWorker` is a worker that is started once and runs in the background as a daemon. It receives and executes tasks from the parent process.

Usage of `PersistenceWorker`:

```
use NHor\PcntlParallel\PersistenceWorker;

$worker = (new PersistenceWorker())
       ->setOnReceiveCallback(function ($job) {
          return $job->handle();
       })
       ->run();

$jobs = [
         new Job($data),
         new Job($data),
         new Job($data)
      ];

foreach ($jobs as $job) {
    $worker->dispatch($job);
}

// do something immediately
//...your code...

// or you can wait for the result of each job
$result[] = $worker->waitOutput(waitTimeout: 2_000); //job1 result
$result[] = $worker->waitOutput(waitTimeout: 2_000); //job2 result

//kill worker
$worker->kill();
```

### PersistenceWorkersPool

[](#persistenceworkerspool)

`PersistenceWorkersPool` A pool of processes for sending tasks. A free worker will be selected to perform the task. If all workers are busy, it will wait until at least one is free. You can specify a maximum wait time, in which case an exception will be thrown.

Usage of `PersistenceWorkersPool`:

```
use NHor\PcntlParallel\PersistenceWorkersPool;

//pool with 5 available workers
$pool = PersistenceWorkersPool::create(5)
  //executed once when a worker is started
  ->setCommonBeforeExecutionCallback(function () {
          DB::reconnect();
          Redis::reconnect();
    })
    ->run(function (mixed $job) {
        sleep(1);
        return $job;
    });

$tasks = [1,2,3,4,5,6,7,8,9];

foreach ($tasks as $task) {
    //1,2,3,4,5 - will be sent immediately, but the next tasks will wait until some worker completes the task.
    $pool->dispatch($task, waitAvailableWorkerTimeout: 2_000_000); //if the wait is more than 2 seconds, an exception will be thrown
}

//retrieve the result available at the moment
$result = $pool->pullWorkersOutput(); //[1,2,3,4,5]

//wait next results
$pool->wait();

$result = $pool->pullWorkersOutput(); //[6,7,8,9]
```

Testing
-------

[](#testing)

```
composer test
```

Credits
-------

[](#credits)

- [Nikolay Horobets](https://github.com/n-hor)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

PHP sandbox:
------------

[](#php-sandbox)

[](https://sandbox.ws)

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance37

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity50

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

Total

3

Last Release

571d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/acdf0fd9706a78b6a9706ac3c1a3b0c58dcc3698f59775b0325a17f99ddc21a0?d=identicon)[n-hor](/maintainers/n-hor)

---

Top Contributors

[![n-hor](https://avatars.githubusercontent.com/u/26003087?v=4)](https://github.com/n-hor "n-hor (12 commits)")

---

Tags

asyncconcurrencyparallel-processingphptask-workerconcurrencyparallelfork

###  Code Quality

TestsPest

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/n-hor-pcntl-parallel/health.svg)

```
[![Health](https://phpackages.com/badges/n-hor-pcntl-parallel/health.svg)](https://phpackages.com/packages/n-hor-pcntl-parallel)
```

###  Alternatives

[spatie/fork

A lightweight solution for running code concurrently in PHP

1.0k2.6M39](/packages/spatie-fork)[veewee/composer-run-parallel

Run composer tasks in parallel

91748.2k13](/packages/veewee-composer-run-parallel)[duncan3dc/fork-helper

Simple class to fork processes in PHP and allow multi-threading

73548.0k4](/packages/duncan3dc-fork-helper)[arara/process

Provides a better API to work with processes on Unix-like systems

16861.7k2](/packages/arara-process)[recca0120/laravel-parallel

64116.7k](/packages/recca0120-laravel-parallel)[bluepsyduck/symfony-process-manager

A process manager for Symfony processes, able to run them in parallel.

10784.6k3](/packages/bluepsyduck-symfony-process-manager)

PHPackages © 2026

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