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

michalfeher's avatar

Horizon Job timeout issue

I am having a hard time with queues and horizon on Forge. On localhost everything works as expected. I have the same horizon config for environment where my app is running on Forge. Specifically:

'supervisor' => [
    'connection' => 'redis',
    'queue' => ['default'],
    'balance' => 'simple',
    'processes' => 21,
    'tries' => 1,
    'timeout' => 0,
],

My problem is jobs are throwing MaxAttemptsExceededException. " A queued job has been attempted too many times or run too long. The job may have previously timed out."

I created testing job where I just sleep it for 70 seconds and then throws "I woke up" exception. On localhost after 70s I get the exception, on forge server I get timeout error.

What should I do in order to get rid of this timeouting? Do I need to run a worker? I thought that setting php artisan horizon deamon is enough.

Thanks for your help.

0 likes
6 replies
ndberg's avatar

Same issue here. Could you find a solution?

michael1986's avatar

+1, got exactly the same issue. Works fine on local machine.

Update: I think it goes wrong when running multiple instances of Horizon on a single server. I just removed one instance which I used for site A, and kept the one for site B. Now it works like a charm.

Chrizzmeister's avatar

Same problem and not running multiple horizon setups on same server. Added different environments for staging/production also

Robstar's avatar

I usually solve the odd Horizon issue I get with one of the following:

  • terminating and then continuing Horizon
  • clicking the 'retry' icon next to the failed job
  • if that fails, it's most likely down to an error with my job class - errors are sometimes easier to view if you use say the database or sync driver (i.e. not Horizon)

I did get a similar issue where a job kept failing a while ago. This was down to my own error - I was using Horizon for two separate systems, both of which were using the same redis database :/ Setting the correct redis db number for each app resolved that.

1 like
ashwinmram's avatar

The last paragraph was the root cause for me! Thanks @robstar :)

I updated config/database.php by using the appropriate environment variables in my .env, i.e. REDIS_DB and REDIS_CACHE_DB.

    'redis' => [

        'client' => env('REDIS_CLIENT', 'predis'),

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'predis'),
        ],

        'default' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => env('REDIS_DB', 0),
        ],

        'cache' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => env('REDIS_CACHE_DB', 1),
        ],

    ],

Thanks to @datune I learned that Redis allows you to have upto 16 databases by default (remember, this is 0-15, not 1-16!)

2 likes
klopma's avatar

Hi folks, could one of you talk through the distinction between the 'timeout' value in the horizon config and the $timeout variable you might set on a job? In my head the 'timeout' value on the horizon config should be larger than the largest $timeout variable on any of my jobs, but I don't really understand the distinction between those two.

Please or to participate in this conversation.