Managing Laravel queue workers with Supervisor on Ubuntu
If you’ve ever SSH’d into a server, run php artisan queue:work, and then watched it die the moment your session closes — Supervisor is the fix. It keeps long-running processes alive, restarts them on failure, and gives you a clean interface to manage them.
What is Supervisor
Supervisor is a process control system for Linux. You give it a config file describing a program, and it makes sure that program stays running. If the process crashes, Supervisor restarts it automatically. It’s the standard tool for running Laravel queue workers, Horizon, websocket servers, or anything that needs to stay alive in the background.
Installing Supervisor
On Ubuntu, it’s a single command:
sudo apt update && sudo apt install supervisor -y
Supervisor runs as a system service out of the box. Confirm it’s active:
sudo systemctl status supervisor
You should see active (running). If not:
sudo systemctl enable supervisor
sudo systemctl start supervisor
Creating a config for Laravel queue:work
Supervisor config files live in /etc/supervisor/conf.d/. Each .conf file defines one or more programs to manage.
Create a new config:
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
Paste the following:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/your-app/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/your-app/storage/logs/worker.log
stopwaitsecs=3600
Note: Replace
/var/www/your-appwith the actual path to your Laravel project, and adjustuserto match whoever owns your app files (oftenwww-dataon Ubuntu with Nginx/Apache).
Config breakdown
| Directive | What it does |
|---|---|
process_name | Names each process instance. The %(process_num)02d suffix gives each one a unique number. |
command | The actual command Supervisor will run and keep alive. |
autostart | Start the process when Supervisor starts (e.g. on boot). |
autorestart | Restart the process if it exits unexpectedly. |
stopasgroup / killasgroup | Ensures child processes are also stopped/killed — important for PHP workers. |
user | The OS user the process runs as. |
numprocs | How many parallel worker processes to run. Scale this based on your workload. |
redirect_stderr | Sends error output to the same log file as stdout. |
stdout_logfile | Where logs are written. |
stopwaitsecs | How long Supervisor waits for a graceful shutdown before killing the process. Match this to --max-time. |
Loading and starting the workers
After saving the config, tell Supervisor to pick it up:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
reread detects new or changed config files. update applies the changes. start kicks off the processes.
Common Supervisor commands
# Check status of all managed processes
sudo supervisorctl status
# Restart your workers (e.g. after a deploy)
sudo supervisorctl restart laravel-worker:*
# Stop workers
sudo supervisorctl stop laravel-worker:*
# Tail the worker log in real time
sudo supervisorctl tail -f laravel-worker:laravel-worker_00
# Reload all configs and restart everything
sudo supervisorctl reload
Restarting workers on deploy
When you deploy new code, your queue workers are still running the old code in memory. You need to restart them. Add this to your deploy script:
sudo supervisorctl restart laravel-worker:*
Or, if you prefer a graceful approach, use Laravel’s built-in signal:
php artisan queue:restart
This tells workers to finish their current job and then exit. Supervisor sees the exit and spawns a fresh process with the new code. This is the cleaner option because no jobs get interrupted mid-execution.
Troubleshooting
If workers aren’t starting, check the Supervisor log first:
sudo tail -f /var/log/supervisor/supervisord.log
Then check your worker log:
sudo tail -f /var/www/your-app/storage/logs/worker.log
Common issues:
- Permission denied — the
userin your config doesn’t have access to the project directory or the PHP binary. - Command not found — use the full path to PHP if needed:
/usr/bin/phpinstead of justphp. - Workers keep restarting — your app is throwing a fatal error on startup. Check
storage/logs/laravel.log.
Quick reference
# Install
sudo apt install supervisor -y
# Create config
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
# Apply config
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
# Check status
sudo supervisorctl status
# Restart after deploy
sudo supervisorctl restart laravel-worker:*
# Or graceful restart via Laravel
php artisan queue:restart
More posts at noukeosombath.com