If your Laravel queue works locally but nothing happens in production, it’s almost always because there’s no worker running. queue:work needs to run continuously, and SSH sessions don’t count.
The correct solution is Supervisor.
Install Supervisor
On your Ubuntu server (via SSH or local CLI):
sudo apt update
sudo apt install supervisor
And then make sure it's running:
sudo systemctl status supervisor
Create A Queue Worker Config
Create the config file, with a name that describes it's purpose:
sudo nano /etc/supervisor/conf.d/laravel-queue.conf
Example config to run on a Redis queue:
[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/php8.2 /var/www/myapp/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/myapp/storage/logs/queue.log
stopwaitsecs=3600
What matters here:
numprocs= the number of workers--triesand--timeoutprotect you from bad jobsstdout_logfileis essential for debugging
Start the Workers
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-queue:*
... and check that they're running:
sudo supervisorctl status
Laravel Config
In your projects .env file make sure your QUEUE_CONNECTION is set to redis.
If you're using database queues, don't forget to publish the migrations and run them for your application;
php artisan queue:table
php artisan migrate
Restart Workers on Deploy
Workers don't automatically reload when code changes, so you'll need to make a call to the queue:restart Artisan command to broadcast the restart signal.
Skipping this is a classic production bug.
Common Issues
Jobs stuck -> Worker not running or watching the wrong queue
Jobs failing silently -> PHP version mismatch
No longs -> Wrong permission on
storage/logs.
Once Supervisor is in place, queues stop being fragile and start being boring - which is exactly what you want.