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

davedriesmans's avatar

Horizon jobs do not always get picked up

We experience a weird issue where jobs are created, they are visible in pending and sometimes picked and sometimes fail (because of a timeout). We work on a dedicated server from a local hosting company (Combell/Openminds).

Currently no idea where to look anymore.

More info:

  • This goes for all jobs. The same job is sometimes immediately processed, sometimes keeps waiting and then goes to the Failed job.
  • Retrying the same job (failed job) results in most cases in a completed job.
  • Strange: in the never-picked-up-job i see Attempts: 2 instead where i expect Attempts: 1 as the config says tried:1

config/horizon.php:

'production' => [
	'supervisor-1' => [
		'connection' => 'redis',
		'queue' => ['default'],
		'balance' => 'auto',
		'processes' => 3,
		'maxProcesses' => 3,
		'memory' => 500,
		'tries' => 1,
		'nice' => 0,
		'timeout' => 170,
		'balanceMaxShift' => 1,
		'balanceCooldown' => 3,
	],
	'mailcoach-general' => [
		'connection' => 'mailcoach-redis',
		'queue' => ['mailcoach', 'mailcoach-feedback', 'send-mail', 'send-automation-mail'],
		'balance' => 'auto',
		'processes' => 1,
		'tries' => 1,
		'timeout' => 60 * 60,
	],
	'mailcoach-heavy' => [
		'connection' => 'mailcoach-redis',
		'queue' => ['send-campaign'],
		'balance' => 'auto',
		'processes' => 1,
		'maxProcesses' => 1,
		'tries' => 1,
		'timeout' => 60 * 60,
	],
],

config/queue.php:

'redis' => [
	'driver' => 'redis',
	'connection' => 'default',
	'queue' => env('REDIS_QUEUE', 'default'),
	'retry_after' => 180,
	'block_for' => null,
	'after_commit' => false,
],
'mailcoach-redis' => [
	'driver' => 'redis',
	'connection' => 'default',
	'queue' => env('REDIS_QUEUE', 'default'),
	'retry_after' => 11 * 60,
	'block_for' => null,
],

ps -aux | grep queue

telraam   64745  0.1  1.8 573772 191084 ?       S    00:03   0:52 /usr/bin/php8.0 artisan horizon:supervisor web-001breadcrumbs-AWWv:supervisor-1 redis --workers-name=default --balance=auto --max-processes=3 --min-processes=1 --nice=0 --balance-cooldown=3 --balance-max-shift=1 --parent-id=64696 --backoff=0 --max-time=0 --max-jobs=0 --memory=500 --queue=default --sleep=3 --timeout=170 --tries=1 --rest=0
telraam   64746  0.1  1.8 574532 191712 ?       S    00:03   0:58 /usr/bin/php8.0 artisan horizon:supervisor web-001breadcrumbs-AWWv:mailcoach-general mailcoach-redis --workers-name=default --balance=auto --max-processes=1 --min-processes=1 --nice=0 --balance-cooldown=3 --balance-max-shift=1 --parent-id=64696 --backoff=0 --max-time=0 --max-jobs=0 --memory=128 --queue=mailcoach,mailcoach-feedback,send-mail,send-automation-mail --sleep=3 --timeout=3600 --tries=1 --rest=0
telraam   64747  0.1  1.8 574684 191508 ?       S    00:03   0:51 /usr/bin/php8.0 artisan horizon:supervisor web-001breadcrumbs-AWWv:mailcoach-heavy mailcoach-redis --workers-name=default --balance=auto --max-processes=1 --min-processes=1 --nice=0 --balance-cooldown=3 --balance-max-shift=1 --parent-id=64696 --backoff=0 --max-time=0 --max-jobs=0 --memory=128 --queue=send-campaign --sleep=3 --timeout=3600 --tries=1 --rest=0
telraam   64827  0.0  0.9 488444 102468 ?       S    00:03   0:12 /usr/bin/php8.0 artisan horizon:work mailcoach-redis --name=default --supervisor=web-001breadcrumbs-AWWv:mailcoach-heavy --backoff=0 --max-time=0 --max-jobs=0 --memory=128 --queue=send-campaign --sleep=3 --timeout=3600 --tries=1 --rest=0
telraam   64828  0.0  0.9 488344 102412 ?       S    00:03   0:12 /usr/bin/php8.0 artisan horizon:work mailcoach-redis --name=default --supervisor=web-001breadcrumbs-AWWv:mailcoach-general --backoff=0 --max-time=0 --max-jobs=0 --memory=128 --queue=mailcoach --sleep=3 --timeout=3600 --tries=1 --rest=0
telraam   64829  0.0  1.0 488348 102652 ?       S    00:03   0:12 /usr/bin/php8.0 artisan horizon:work mailcoach-redis --name=default --supervisor=web-001breadcrumbs-AWWv:mailcoach-general --backoff=0 --max-time=0 --max-jobs=0 --memory=128 --queue=mailcoach-feedback --sleep=3 --timeout=3600 --tries=1 --rest=0
telraam   64831  0.0  0.9 488424 101864 ?       S    00:03   0:12 /usr/bin/php8.0 artisan horizon:work mailcoach-redis --name=default --supervisor=web-001breadcrumbs-AWWv:mailcoach-general --backoff=0 --max-time=0 --max-jobs=0 --memory=128 --queue=send-mail --sleep=3 --timeout=3600 --tries=1 --rest=0
telraam   64833  0.0  0.9 488312 102460 ?       S    00:03   0:12 /usr/bin/php8.0 artisan horizon:work mailcoach-redis --name=default --supervisor=web-001breadcrumbs-AWWv:mailcoach-general --backoff=0 --max-time=0 --max-jobs=0 --memory=128 --queue=send-automation-mail --sleep=3 --timeout=3600 --tries=1 --rest=0
telraam  120128  1.7  0.8 547896 91504 ?        S    11:25   0:01 /usr/bin/php8.0 artisan horizon:work redis --name=default --supervisor=web-001breadcrumbs-AWWv:supervisor-1 --backoff=0 --max-time=0 --max-jobs=0 --memory=500 --queue=default --sleep=3 --timeout=170 --tries=1 --rest=0
telraam  120129  1.6  0.8 547896 91224 ?        S    11:25   0:01 /usr/bin/php8.0 artisan horizon:work redis --name=default --supervisor=web-001breadcrumbs-AWWv:supervisor-1 --backoff=0 --max-time=0 --max-jobs=0 --memory=500 --queue=default --sleep=3 --timeout=170 --tries=1 --rest=0
telraam  120435  2.1  0.9 556320 100412 ?       S    11:25   0:01 /usr/bin/php8.0 artisan horizon:work redis --name=default --supervisor=web-001breadcrumbs-AWWv:supervisor-1 --backoff=0 --max-time=0 --max-jobs=0 --memory=500 --queue=default --sleep=3 --timeout=170 --tries=1 --rest=0
telraam  123568  0.0  0.0  12388   892 pts/0    S+   11:26   0:00 grep queue

Where should i look to solve this?

0 likes
9 replies
jorgensolli's avatar

If the never-picked-up-job has attempts: 2, it was most certainly attempted at some point.

Are you logging anything in these jobs? If not, I'd probably start there. Add some logging in every job's constructor and their handle method so you can verify whether or not the job is in fact picked up or not.

Also, are all your jobs configured the same? Any unique rules or anything like that?

1 like
davedriesmans's avatar

I have some dummy test jobs that i run on the server. Locally I never experience the issue.

       $rand = substr(md5(microtime()),rand(0,26),3);
        $batchNr = $rand.'-'.Carbon::now()->format('Hi-s');

        $job = (new SendFiveQueueTests($batchNr.'--1'));
        dispatch($job);
        sleep(2);

        $job = (new SendFiveQueueTests($batchNr.'--2'));
        dispatch($job);
        sleep(2);

        $job = (new SendFiveQueueTests($batchNr.'--3'));
        dispatch($job);
        sleep(2);

        $job = (new SendFiveQueueTests($batchNr.'--4'));
        dispatch($job);
        sleep(2);

        $job = (new SendFiveQueueTests($batchNr.'--5'));
        dispatch($job);
        sleep(2);
```

and then:

```
 public function handle()
    {

        Log::channel('joblogs')->debug('- SendFiveQueueTests started '. $this->traceParam);

        for ($i = 1; $i <= 10000000; $i++) {
            // doing nothing
        }

        Log::channel('joblogs')->debug('--- SendFiveQueueTests Done! '.$this->traceParam);

    }

So created about 60 jobs with the test endpoint. Only one of them wasn't picked up and failed.

The handle was never triggered as the logs didn't have the SendFiveQueueTests started ... message with that traceParam for that failed job. It showed Attempts: 2 however. Mystery! :)

jorgensolli's avatar

@davedriesmans The only thing I can think of is the Job being released back into the queue for whatever reason. That would result in the attempt increasing by one, and since you have set attempts to 1, it would cause the job to fail the second time around.

Are you sure there's no configuration that would cause the jobs to be released back into the queue?

1 like
davedriesmans's avatar

@jorgensolli

Are you sure there's no configuration that would cause the jobs to be released back into the queue?

No not sure, there must be something, but no idea where to look.

davedriesmans's avatar

@jorgensolli

Here it is

(However it happens with all jobs. Most of the time they run fine, but sometimes randomly not. So the same job goes fine one moment, another moment not.)

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Log;


class SendFiveQueueTests implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $traceParam;

    public function __construct($traceParam)
    {
        $this->traceParam = $traceParam;
    }
    
    public function handle()
    {
        Log::channel('joblogs')->debug('- SendFiveQueueTests started '. $this->traceParam);
        for ($i = 1; $i <= 10000000; $i++) {
            // doing nothing
        }
        Log::channel('joblogs')->debug('--- SendFiveQueueTests Done! '.$this->traceParam);

    }
    
}
LaraBABA's avatar

Hi,

As you seem to be sending emails, are you sure you do not have a time-out on the side of your mail provider?

ie: You have a limit of xxx amount of emails per minute allowed to be sent?

I am wondering if some emails are trying to be sent too rapidly, causing a time-out between you and the email host. As the email struggles to be sent, it causes issues with subsequent queues.

I am just thinking that perhaps when you send your emails and it works, you set a column to 1. And then because the job fails, it never reaches 1 and stays to 0 which creates some kind of loop back from your cron jobs that sends the job back again to the queue.

Just an idea......

davedriesmans's avatar

Hi @michael bramer

In the end the hosting company solved it by:

  • increasing the timeout on the redis server, it was extended to one hour
  • adding the phpredis extension (instead of just predis)
1 like

Please or to participate in this conversation.