Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SNaRe's avatar
Level 7

How to dynamically generate queues in Laravel Horizon

My application requires to have dynamically generated queues with some prefix like

"process_user_1", "process_user_2", "process_user_n"

The main idea is to separate execution of some jobs depends on model ID.

Because the api that I connect allows only 1 connection for a user

Normally I can configure in horizon.php but it should be dynamic e.g. I can have 1000 users so I must have 1000 different queues

What could be the solution?

This is my configuration

'User-1' => [ 'connection' => 'redis', 'queue' => ['User-1'], 'balance' => 'simple', 'processes' => 1, 'tries' => 10, ], 'User-2' => [ 'connection' => 'redis', 'queue' => ['User-2'], 'balance' => 'simple', 'processes' => 1, 'tries' => 10,

0 likes
8 replies
bobbybouwmann's avatar
Level 88

Well you can dynamically set the config on a request right? You can probably do that in a middleware or a service provider.

Note: I know that the middleware way works, but I'm not sure if the service provider way works

Here is an example for setting all the configs per user.

public function handle()
{
    $users = User::all();

    foreach ($users as $user) {
        Config::set('horizon.environments.production.user-'. $user->id, [
            'connection' => 'redis',
            'queue' => ['default'],
            'balance' => 'simple',
            'processes' => 10,
            'tries' => 3,
        ]);
    }
}

Note that I'm not a big fan of this. Handling a queue per user sounds like a bad idea and a waste of resources. My advice would be to have a queue per domain of your site. So for example a queue for emails, a queue for processing images and a queue for the other stuff.

1 like
SNaRe's avatar
Level 7

Thanks for your reply :) You said that "I'm not a big fan of this" what could be other solutions ? In my case I have thousands of jobs for every user and these jobs should be processed one by one for every user

Helmchen's avatar

The problem with the current configuration is that you probably end up with hundreds of workers that do nothing, if all tasks for a specific user are done. they eat memory and cpu and can not do something else on other busy queues, so you loose the power of the balance strategies.

I think it would be better you have X processes working on Y queues, so just append to the queues array instead of defining 1000 separate worker configurations.

'supervisor-1' => [
    'connection' => 'redis',
    'queue' => ['default', 'emails', 'user-1', 'user-2', 'user-3', 'user-4'],
    'balance' => 'auto',
    'processes' => 100,
    'tries' => 3,
],          

Now you should have 100 processes that should jump back and forth between the queues, wherever there is much to do.

2 likes
bobbybouwmann's avatar

Well like I said. I would probably use a handful of queues that would handle the related tasks for a user. It can be any user at that point. A queue is only there to postpone tasks that are not necessary for the current request. If you have a lot of jobs for later usages you should have enough resources for those queues and let them handle 100 processes at once. You will need a big server for that, but it's possible ;)

1 like
bobbybouwmann's avatar

Well the reply from @Helmchen is exactly what I mean! Run multiple processes on x number of queues. You can of course add an extra server (supervisor-2), but first start with multiple processes and queues.

1 like
SNaRe's avatar
Level 7

Thanks you all for your kind responses but if I set balance to auto user-2 can have 30 processes but it shouldnt be more than 1.

Do you have a solution for this?

And can I add dynamically queues array like the solution in middleware method?

Thanks a lot

Helmchen's avatar

I would probably leave it up to the job to do it in parallel or not. With thousands of jobs per user you break your neck with the limitation to 1 worker per queue.

Redis has some nice concurrency features in Laravel, which I am also looking at myself.

https://laravel.com/docs/5.6/queues#rate-limiting

Although I'm not sure how the performance looks like if you really have thousands of jobs per user.

1 like

Please or to participate in this conversation.