# Digging the new Concurrency Facade from Laravel & the Early Review

Hey guys,

From **LaraconUS 2024,** Taylor shared with us a lot of cool stuff. From the code, and the framework to the infrastructure. PHP and Laravel are getting hot more than ever 🔥

A new Facade has been shared & released in the latest version: the `Concurrency`

Let’s check it out and I’ll share my early review on that.

## The Concurrency Facade

### Introduction

The `Concurrency` facade helps us to run tasks **concurrently**.

* Before, tasks need to be run **synchronously**.
    
* After `laravel/framework` [v11.23.2](https://github.com/laravel/framework/releases/tag/v11.23.2), with `Concurrency`, we can run the tasks **asynchronously\***
    
    * learn more about the **\*** in the **Digging Deeper** section below.
        

With that, we can dispatch and run our tasks (instead of one by one) and we ***can*** have

### Usage

```php
// $res is a Collection<Result>
$res = Concurrency::run([
    fn () => MyTask::run(),
    fn () => MyOtherTask::run(), 
]);

$res[0] // access the result
```

## Digging deeper into the Concurrency Facade

Let’s check out the implementation.

At first glance, there are 2 drivers that we can use:

* [ProcessDriver](https://github.com/laravel/framework/blob/11.x/src/Illuminate/Concurrency/ProcessDriver.php)
    
* [ForkDriver](https://github.com/laravel/framework/blob/11.x/src/Illuminate/Concurrency/ForkDriver.php) (uses `spatie/fork`)
    

Since I always have a thing for the `in-house` stuff, I’ll only review `ProcessDriver` for this blog posting.

### How does the ProcessDriver work?

Looking at the `run` driver, it will **serialize our closure** and **send it to a new Console command** that Laravel introduced.

That command will **invoke the closure** and return the result.

So we can see, **1 concurrent task = 1 console command process**.

### Considerations / Problems / Flaws

* Each task process will **bootstrap a whole application again**.
    
    * This could **increase** the number of DB connections.
        
* Having many processes would **decrease** the overall **server's performance.**
    
    * Probably worse in the serverless environment (AWS Lambda)
        
* It *might* have some **out-of-context issues** if the concurrent task has **dependencies** (e.g.: using `$this->something` reference)
    
* It uses the `Promise.all` approach instead of the `Promise.allSettled`.
    
    * So if there is ***an error***, we won't get all the successful results (get an `Exception` instead)
        

### Reviews

#### Small tasks

It’s not probably a good idea to use `Concurrency` for **many small tasks**, reasons:

* It has to bootstrap the whole application for each task, the overall bootstrap can take from **10~70ms** depending on the server’s gig & codebase’s size.
    
* Many processes **will slow down** the overall server’s performance.
    
* There is no way to get successful results if there is an error in the middle. Perhaps this is something Laravel will need to improve soon.
    

I was thinking of doing something like:

```php
Concurrency::run(
    $users->map(
        fn (User $user) => fn () => SendWelcomeEmailJob::dispatch($user)
    )
);
```

But after digging a bit, I’m still sticking with the normal `foreach` and `dispatch` 🥹 It’s way more optimal for the time being.

#### Large Tasks

If we can **manage** **how** **many tasks we’re going to dispatch**. Perhaps we can use Concurrency for large tasks (e.g.: concurrent 3rd party API calls).

## Conclusion

Well, guys, I’m still sticking with normal Laravel stuff and Queue Jobs at the time being hehe. Things are too early for the very best, let’s wait for a while for the improvements from Laravel’s Core Team and the lovely huge Laravel Community.

Currently, PHP is not a language designed to ***run things concurrently*** in a process. Most of the things are workaround solutions.

* The same goes for `fork` from Spatie, creating processes to run tasks.
    

If you are using `Octane` x `Swoole`, then you can use the concurrency from Swoole which utilizes the **Event Loop** (the brain of JS), totally better.

Thanks for reading!
