# Concurrency * Introduction * Running Concurrent Tasks * Deferring Concurrent Tasks ## Introduction Sometimes you may need to execute several slow tasks which do not depend on one another. In many cases, significant performance improvements can be realized by executing the tasks concurrently. Laravel's `Concurrency` facade provides a simple, convenient API for executing closures concurrently. #### How it Works Laravel achieves concurrency by serializing the given closures and dispatching them to a hidden Artisan CLI command, which unserializes the closures and invokes it within its own PHP process. After the closure has been invoked, the resulting value is serialized back to the parent process. The `Concurrency` facade supports three drivers: `process` (the default), `fork`, and `sync`. The `fork` driver offers improved performance compared to the default `process` driver, but it may only be used within PHP's CLI context, as PHP does not support forking during web requests. Before using the `fork` driver, you need to install the `spatie/fork` package: 1composer require spatie/fork composer require spatie/fork The `sync` driver is primarily useful during testing when you want to disable all concurrency and simply execute the given closures in sequence within the parent process. ## Running Concurrent Tasks To run concurrent tasks, you may invoke the `Concurrency` facade's `run` method. The `run` method accepts an array of closures which should be executed simultaneously in child PHP processes: 1use Illuminate\Support\Facades\Concurrency; 2use Illuminate\Support\Facades\DB; 3  4[$userCount, $orderCount] = Concurrency::run([ 5 fn () => DB::table('users')->count(), 6 fn () => DB::table('orders')->count(), 7]); use Illuminate\Support\Facades\Concurrency; use Illuminate\Support\Facades\DB; [$userCount, $orderCount] = Concurrency::run([ fn () => DB::table('users')->count(), fn () => DB::table('orders')->count(), ]); To use a specific driver, you may use the `driver` method: 1$results = Concurrency::driver('fork')->run(...); $results = Concurrency::driver('fork')->run(...); Or, to change the default concurrency driver, you should publish the `concurrency` configuration file via the `config:publish` Artisan command and update the `default` option within the file: 1php artisan config:publish concurrency php artisan config:publish concurrency ## Deferring Concurrent Tasks If you would like to execute an array of closures concurrently, but are not interested in the results returned by those closures, you should consider using the `defer` method. When the `defer` method is invoked, the given closures are not executed immediately. Instead, Laravel will execute the closures concurrently after the HTTP response has been sent to the user: 1use App\Services\Metrics; 2use Illuminate\Support\Facades\Concurrency; 3  4Concurrency::defer([ 5 fn () => Metrics::report('users'), 6 fn () => Metrics::report('orders'), 7]); use App\Services\Metrics; use Illuminate\Support\Facades\Concurrency; Concurrency::defer([ fn () => Metrics::report('users'), fn () => Metrics::report('orders'), ]);