Laravel Concurrency Facade &amp; Process Pools | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Laravel Concurrency Facade and Process Pools for Parallel Work        On this page       1. [  Running Independent Work in Parallel with Laravel's Concurrency Facade ](#running-independent-work-in-parallel-with-laravels-concurrency-facade)
2. [  When to Reach for Concurrency vs. Queues ](#when-to-reach-for-concurrency-vs-queues)
3. [  The Concurrency Facade ](#the-concurrency-facade)
4. [  Deferring Non-Critical Work ](#deferring-non-critical-work)
5. [  Process Pools for Fine-Grained Control ](#process-pools-for-fine-grained-control)
6. [  Timeout and Error Handling ](#timeout-and-error-handling)
7. [  Practical Gotchas ](#practical-gotchas)
8. [  Takeaways ](#takeaways)

  ![Laravel Concurrency Facade and Process Pools for Parallel Work](https://cdn.msaied.com/392/fd3c54592355d96441888fa19c2674a0.png)

  #laravel   #concurrency   #process   #performance  

 Laravel Concurrency Facade and Process Pools for Parallel Work 
================================================================

     8 Jul 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   Running Independent Work in Parallel with Laravel's Concurrency Facade  ](#running-independent-work-in-parallel-with-laravels-concurrency-facade)
2. [  02   When to Reach for Concurrency vs. Queues  ](#when-to-reach-for-concurrency-vs-queues)
3. [  03   The Concurrency Facade  ](#the-concurrency-facade)
4. [  04   Deferring Non-Critical Work  ](#deferring-non-critical-work)
5. [  05   Process Pools for Fine-Grained Control  ](#process-pools-for-fine-grained-control)
6. [  06   Timeout and Error Handling  ](#timeout-and-error-handling)
7. [  07   Practical Gotchas  ](#practical-gotchas)
8. [  08   Takeaways  ](#takeaways)

 Running Independent Work in Parallel with Laravel's Concurrency Facade
----------------------------------------------------------------------

Most Laravel applications are embarrassingly sequential: fetch a remote API, transform the result, hit another API, aggregate. Each step blocks the next. The Concurrency facade (introduced in Laravel 11) and the lower-level `Process` facade give you two complementary tools to break that pattern without spinning up a queue.

### When to Reach for Concurrency vs. Queues

Queues are the right tool when work is fire-and-forget, retryable, or needs to survive a process restart. The Concurrency facade is the right tool when:

- You need the results **now**, in the same request or command.
- Tasks are independent (no shared mutable state).
- Total wall-clock time matters more than throughput.

### The Concurrency Facade

```php
use Illuminate\Support\Facades\Concurrency;

[$orders, $inventory, $pricing] = Concurrency::run([
    fn () => Order::forUser($userId)->latestSummary(),
    fn () => Inventory::forUser($userId)->available(),
    fn () => Pricing::forUser($userId)->current(),
]);

```

Each closure runs in a **forked child process** (via the `fork` driver on Linux/macOS) or a separate PHP process (via the `process` driver on Windows or when `pcntl` is unavailable). Results are serialized back to the parent automatically.

The driver is resolved from `config/concurrency.php`:

```php
// config/concurrency.php
return [
    'default' => env('CONCURRENCY_DRIVER', 'fork'),
];

```

Switch to `process` in environments where `pcntl` is absent:

```bash
CONCURRENCY_DRIVER=process

```

### Deferring Non-Critical Work

`Concurrency::defer()` schedules closures to run **after the response is sent**, similar to `response()->then()` but composable:

```php
Concurrency::defer([
    fn () => Cache::tags('reports')->flush(),
    fn () => AuditLog::record($event),
]);

```

This is useful for cache warming or audit writes that must not delay the response.

### Process Pools for Fine-Grained Control

When you need more control — custom environment variables, timeouts, or streaming output — the `Process` facade's pool API is the right abstraction:

```php
use Illuminate\Support\Facades\Process;

$results = Process::pool(function ($pool) {
    $pool->command('php artisan report:generate --type=sales');
    $pool->command('php artisan report:generate --type=inventory');
    $pool->command('php artisan report:generate --type=returns');
})->start()->wait();

foreach ($results as $result) {
    throw_if($result->failed(), RuntimeException::class, $result->errorOutput());
    logger()->info($result->output());
}

```

Each pool entry is a real OS process. You get `output()`, `errorOutput()`, `exitCode()`, and `failed()` on every result.

### Timeout and Error Handling

Both APIs respect timeouts. With `Concurrency::run()` the timeout is per-closure:

```php
Concurrency::run([
    fn () => slowExternalApi(),
], timeout: 5); // seconds

```

With `Process::pool()` set it per command:

```php
$pool->command('php artisan heavy:task')->timeout(30);

```

Always handle failures explicitly. Unhandled exceptions in forked closures are re-thrown in the parent after all tasks complete.

### Practical Gotchas

**Database connections are not inherited.** Each forked process must reconnect. Laravel handles this automatically for Eloquent calls inside closures, but if you pass an open PDO handle explicitly you will get a broken pipe.

**Avoid shared mutable state.** Closures capture variables by value after forking. Writes inside a closure do not propagate back to the parent scope — only the return value does.

**Octane users:** Under Octane the worker process is long-lived. `pcntl_fork()` inside a Swoole coroutine is unsafe. Use the `process` driver or avoid `Concurrency` inside Swoole coroutine context entirely.

### Takeaways

- Use `Concurrency::run()` when you need parallel results synchronously in the same request.
- Use `Concurrency::defer()` for fire-and-forget work that should not block the response.
- Use `Process::pool()` when you need OS-level process control, streaming output, or shell commands.
- Always set timeouts; never assume external work completes in bounded time.
- Switch to the `process` driver on Windows or inside Swoole workers to avoid `pcntl` conflicts.
- Return values are serialized — keep them small and serializable.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-concurrency-facade-and-process-pools-for-parallel-work-3&text=Laravel+Concurrency+Facade+and+Process+Pools+for+Parallel+Work) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-concurrency-facade-and-process-pools-for-parallel-work-3) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Does the Concurrency facade work on shared hosting or Windows?        The default `fork` driver requires `pcntl`, which is unavailable on Windows and many shared hosts. Set `CONCURRENCY_DRIVER=process` to fall back to spawning separate PHP processes, which works everywhere PHP CLI is available. 

      Q02  Can I share an Eloquent model instance between Concurrency closures?        No. After forking, each child has its own memory space. Pass primitive identifiers (IDs, arrays) into closures and re-query inside them. The database connection is re-established automatically per child process. 

      Q03  What is the difference between Concurrency::run() and Process::pool()?        `Concurrency::run()` executes PHP closures in parallel and returns their return values. `Process::pool()` runs arbitrary shell commands as OS processes and gives you stdout, stderr, and exit codes. Use closures for PHP logic, pools for CLI commands or external binaries. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![HTTP Query Method Support in Laravel 13.19](https://cdn.msaied.com/394/4c917aad559beddb5eeb9a7a1e107f4c.png) Laravel Laravel 13 HTTP Client 

### HTTP Query Method Support in Laravel 13.19

Laravel 13.19 adds Http::query() for the HTTP QUERY verb, query/queryJson testing helpers, a reduceInto() coll...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 8 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/http-query-method-support-in-laravel-1319) [ ![Blackfire & Xdebug Profiling in Laravel: Finding Real Bottlenecks in Production-Like Environments](https://cdn.msaied.com/393/a8dfc4ec52c4febc3ef41a491eb452ea.png) laravel performance profiling 

### Blackfire &amp; Xdebug Profiling in Laravel: Finding Real Bottlenecks in Production-Like Environments

Stop guessing where your Laravel app is slow. This guide walks through practical Blackfire and Xdebug profilin...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 8 Jul 2026     4 min read  

  Read    

 ](https://msaied.com/articles/blackfire-xdebug-profiling-in-laravel-finding-real-bottlenecks-in-production-like-environments) [ ![Laravel Cloud Security Defaults Behind Every Deploy](https://cdn.msaied.com/395/28df8f542fbe81ecee3ba4ad897f36d6.png) Laravel Cloud Security PHP 

### Laravel Cloud Security Defaults Behind Every Deploy

Laravel Cloud ships WAF rules, DDoS mitigation, automatic PHP patching, SOC 2 Type II compliance, and deploy-t...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 8 Jul 2026     4 min read  

  Read    

 ](https://msaied.com/articles/laravel-cloud-security-defaults-behind-every-deploy) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
