Fix queued jobs that are not being processed

llms.txt

A queued job is a task your application put aside to do later: send an email, resize an image, call an API. A queue worker is the long-running process that picks those tasks up. If jobs pile up and nothing happens, the worker is not running, is looking at the wrong queue, or is running old code.

This article follows the quickest path to the cause: confirm the worker exists and is running, restart it, make its settings match your application, and check what the application itself says. SrvYard supervises the worker with Supervisor, which restarts it if it crashes, so a stopped worker nearly always has a reason you can read.

Before you begin

  • A queue driver that is not sync. With QUEUE_CONNECTION=sync, jobs run immediately inside the web request and no worker is needed. For database, redis and similar, a worker is required. Check it under Environment in the site.
  • Rights. Seeing the processes needs view access to the site; changing them needs permission to manage queues (sites:manage-queues). See Roles and permissions.
  • A rough count. How many jobs are waiting, and for how long? Jobs that fail are a different problem from jobs that never start, and the checks differ.
Note

A worker holds your application's code in memory. After a deployment it keeps running the old code until it restarts. SrvYard's default deploy script restarts queue workers for you (the $RESTART_QUEUES() line). If you wrote your own script, make sure it does the same.

1. Find the worker

Open the site and choose Processes.

The Processes tab of a Laravel site
The Processes tab: the worker, its process count and status, and the scheduler line.
  1. Add background process. Creates a worker or any other long-running command. Use it if the list is empty.
  2. The worker row. Shows the name, the full command (here php artisan queue:work redis --sleep=3 --tries=3 --max-time=3600), how many Processes run in parallel and the Status. Running is what you want. Anything else on a worker you expect to be busy is your lead.
  3. Scheduler. The Scheduled jobs card shows the Laravel scheduler line (schedule:run, every minute). The scheduler is a separate thing: it dispatches scheduled jobs, the worker runs queued ones. If scheduled tasks never get queued, check this line first.

If there is no worker at all, that is the whole problem: nothing ever consumed the queue. Create one in step 3.

A site that uses Laravel Horizon has a different shape.

A site that runs Laravel Horizon
A Horizon site runs one supervised process; Horizon manages its own workers.
  1. php artisan horizon. One supervised process. Horizon starts and manages its own worker processes according to config/horizon.php, so a single row is normal. The dashboard at /horizon shows the queues and workers.

2. Restart the worker

Open the actions menu at the end of the worker's row.

The actions menu of a background process
Restart makes the workers load new code; View logs shows why they stopped.
  1. Restart. Stops the workers and starts them again, so they load the current code and configuration. This is the first thing to try after a deployment or an .env change. A restart is graceful for a worker between jobs, but a job that is running when you restart may be interrupted.
  2. View logs. Opens the process's own log file. A worker that crashes at once writes the exception here. If SrvYard cannot read the file at the moment, the panel says so; check the server's connection.
  3. Edit. Change the command, the number of processes or the user. The menu also has Start, Stop and Delete.

If the status is Stopped or Failed, press Start or Restart and then watch the log. A worker that stops again within seconds has a command that fails: a wrong PHP path, a missing artisan, a PHP version that was removed, or an exception in your boot code.

3. Make the settings match your application

A worker that runs but processes nothing usually listens to a different queue than your application writes to. Open the new-process panel to see the options that matter.

The New background process panel with the queue worker preset
The queue worker preset builds the artisan command for you; check the preview.
  1. Queue worker. The preset that builds the queue:work command. Custom lets you type any command.
  2. Preview. The exact command that Supervisor will run. Compare it with your application's configuration.
  3. Create background process. Saves it and starts it.

The options to compare:

Option What it must match
connection QUEUE_CONNECTION in the site's .env (redis, database, sqs ...). A worker on database will never see jobs in redis.
--queue The queue names your jobs are dispatched to, comma separated, in priority order, for example high,default. Jobs on a queue the worker does not list wait forever.
processes How many workers run in parallel. Raise it if jobs arrive faster than they finish.
--tries and --backoff How often and how soon a failed job is retried.
--timeout How long one job may run. It must be lower than the retry setting of the connection (retry_after), or jobs run twice.
--memory The worker restarts itself when it uses more than this many MB. A very low value makes it restart constantly.
php The PHP version. Use the same as the site.
Warning

A --timeout shorter than your slowest job kills it halfway, and it is retried. Set it above the longest legitimate job.

4. Check the application's view

If the worker is running and the settings match, look at the application:

  • Queue backend. For redis, check that the Redis service is running on the server (Services) and that REDIS_HOST and the password in .env are right. For database, check that the jobs table exists (run php artisan migrate).
  • Failed jobs. Run php artisan queue:failed under Commands on the site. Failed jobs mean the worker is fine and your jobs throw exceptions: fix the code, then php artisan queue:retry all.
  • Maintenance mode. A worker does not process jobs while the application is down for maintenance unless it runs with --force.
  • Scheduled tasks that never run. Check the scheduler line in step 1, and that the cron job is Installed.
  • Memory. A worker that the system kills for using too much memory shows up as repeated restarts in its log. See Disk full, out of memory or a slow server.

5. Test the worker end to end

Do not wait for a real job to find out. Dispatch a harmless one and watch it go through:

  1. In Commands on the site, run php artisan tinker --execute 'dispatch(fn () => logger("queue test"));'.
  2. Open Logs, choose the Laravel log and press Refresh. A line reading queue test appears within a few seconds if the worker is healthy.
  3. If nothing appears, open Processes, check the status of the worker again and read its log with View logs.
Tip

Keep this check in mind after every change to the queue connection, the PHP version or the Redis password. All three have broken workers silently before.

Troubleshooting

  • Jobs run twice. The job takes longer than the connection's retry_after, so it is handed out again. Raise retry_after above --timeout, or shorten the job.
  • Jobs run old code after a deploy. The workers were not restarted. Add the restart to the deploy script, or press Restart by hand.
  • The worker row shows 0 processes. The process count was set to zero or the program failed to start. Edit it and read the log.
  • It works on my machine but not here. Your local queue is probably sync. Compare QUEUE_CONNECTION in both .env files.
  • Horizon says "inactive" in its dashboard. The supervised php artisan horizon process is stopped; start it from Processes. Horizon also needs the queue connection to be Redis.
  • Only one of two sites processes jobs. Each site has its own workers. Check Processes on the other site.
Last updated 2026-10-247 min readNeed help? Contact support