Documentation Index
Fetch the complete documentation index at: https://kawax.biz/llms.txt
Use this file to discover all available pages before exploring further.
What is concurrency?
When you run multiple independent tasks sequentially—such as fetching data from several external APIs or executing multiple database aggregations—the total time equals the sum of each individual task’s time. Running those tasks concurrently means the total time equals the duration of the single longest task. Laravel’sConcurrency facade provides a simple API for this pattern.
The
Concurrency facade is available in Laravel 13. The default process driver works without any additional packages.How it works
Laravel achieves concurrency by serializing the closures you pass in, dispatching them to a hidden Artisan CLI command, and executing each in its own PHP child process. After each closure finishes, the result is serialized back to the parent process. Three drivers are available:| Driver | Description |
|---|---|
process | Default. Spawns child PHP processes. Works in both web requests and CLI. |
fork | Requires spatie/fork. Forks the current process for better performance. CLI only. |
sync | Executes closures sequentially in the current process. Useful for testing. |
Running concurrent tasks
Pass an array of closures toConcurrency::run(). The return value is an array of each closure’s result, in the same order:
Choosing a driver
Use thedriver() method to select a specific driver for one call:
default option:
The fork driver
The fork driver is faster than process because it forks the running PHP process instead of booting a fresh one. However, PHP does not support forking during web requests, so this driver only works in Artisan commands and queue workers.
Install the required package before using it:
Deferring tasks with defer()
Use Concurrency::defer() when you want to run tasks concurrently after the HTTP response has been sent to the user. The closures are not executed when defer() is called—they run in the background after the response is returned.
Practical examples
Calling multiple external APIs at once
Without concurrency, three one-second API calls take three seconds total. With concurrency, they take roughly one second:Running multiple database aggregations
Testing
UseConcurrency::fake() in tests to switch to the sync driver, which executes closures sequentially without spawning child processes:
CONCURRENCY_DRIVER=sync in .env.testing to apply this globally across all tests.
Caveats
Closures must be serializable
Closures must be serializable
Laravel serializes closures to pass them to child processes. You cannot capture objects that are not serializable (database connections, file handles, open resources). Acquire those resources inside the closure instead.
Process driver overhead
Process driver overhead
Spawning a child PHP process takes time. If a task takes only a few milliseconds, the overhead of the
process driver may outweigh the benefit. Concurrency shines for tasks that take 100 ms or more, such as HTTP requests or heavy database queries.Exceptions in concurrent tasks
Exceptions in concurrent tasks
If a closure throws an exception,
run() re-throws it to the caller. If you want other closures to continue when one fails, wrap the body in a try/catch and return a fallback value.Queues
Learn how to defer work to background jobs using Laravel queues.