Laravel Concurrency Facade &amp; Process Pools | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. Laravel Concurrency Facade and Process Pools for Parallel Work

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

 The Laravel Concurrency facade and Process pools let you run independent tasks in parallel without reaching for a queue. Learn how to structure parallel work safely and squeeze real throughput gains.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 8 Jul 2026 · Updated 8 Jul 2026 · 3 min read

ShareCopy linkCopied

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

  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)

 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.

- [laravel](https://www.msaied.com/public/articles?search=laravel)
- [concurrency](https://www.msaied.com/public/articles?search=concurrency)
- [process](https://www.msaied.com/public/articles?search=process)
- [performance](https://www.msaied.com/public/articles?search=performance)

 Frequently asked questions 
---------------------------

  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.

   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.

   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.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

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

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleMySQL Query Profiling in Laravel: EXPLAIN ANALYZE, Slow Query Log, and Index Tuning](https://www.msaied.com/public/articles/mysql-query-profiling-in-laravel-explain-analyze-slow-query-log-and-index-tuning) [Next articleShip AI with Laravel: How to Stop Your AI Agent from Leaking Everything](https://www.msaied.com/public/articles/ship-ai-with-laravel-how-to-stop-your-ai-agent-from-leaking-everything)  

   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)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
