Manage Background Processes on VPS with Supervisor

Manage Background Processes on VPS with Supervisor

June 2026 · 6 min read

Supervisor is a process control system written in Python designed to monitor and control background processes on Unix/Linux. It's commonly used for Laravel Queue Workers, Celery workers, Python bots, or services that don't have a systemd unit file. This article shows you how to set up Supervisor to manage processes that need to run continuously.

Installing Supervisor

sudo apt update
sudo apt install supervisor -y
sudo systemctl enable --now supervisor

# Check status
sudo supervisorctl status

Adding Program Config

Create a config file in /etc/supervisor/conf.d/ for each program:

sudo nano /etc/supervisor/conf.d/laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/myapp/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/supervisor/laravel-worker.log
stopwaitsecs=3600
# Python worker example
[program:celery-worker]
command=/home/ubuntu/myapp/venv/bin/celery -A myapp worker --loglevel=info
directory=/home/ubuntu/myapp
user=ubuntu
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/celery.log
stderr_logfile=/var/log/supervisor/celery-error.log

supervisorctl Commands

# Reload config
sudo supervisorctl reread
sudo supervisorctl update

# View all status
sudo supervisorctl status

# start/stop/restart
sudo supervisorctl start laravel-worker:*
sudo supervisorctl stop laravel-worker:*
sudo supervisorctl restart laravel-worker:*

# View logs in real-time
sudo supervisorctl tail -f laravel-worker:laravel-worker_00
Tip: numprocs=4 creates 4 processes named laravel-worker_00 to laravel-worker_03. Use the wildcard laravel-worker:* to control all processes at once.

Supervisor Web Interface

sudo nano /etc/supervisor/supervisord.conf

# Add to [inet_http_server]
[inet_http_server]
port = 127.0.0.1:9001  # bind to localhost only
username = admin
password = SecurePassword123
sudo supervisorctl reload
# Access http://localhost:9001 via SSH tunnel

Verify Supervisor is Working Correctly

# Check if supervisord is running
systemctl status supervisor

# View all processes
sudo supervisorctl status

# Get PID of a process
sudo supervisorctl pid laravel-worker:laravel-worker_00

# View logs
sudo tail -f /var/log/supervisor/laravel-worker.log
Tip: If a process status shows BACKOFF, it means the process is crashing repeatedly too quickly. Check the logs to find the cause. With the default startretries=3, after retries are exhausted, the status becomes FATAL.

Common Issues & Troubleshooting

supervisorctl status shows STOPPED or FATAL

The command in the config is wrong, or the user lacks permission to run it. Check the logs to find the error:

# View process logs
sudo tail -50 /var/log/supervisor/laravel-worker.log

# Test run the command directly
sudo -u www-data php /var/www/myapp/artisan queue:work redis --once

New config not loading

You must run reread and update after editing config, not just reload:

sudo supervisorctl reread   # Read new config
sudo supervisorctl update   # Apply changes
sudo supervisorctl status   # Check result

Process consuming increasing memory (memory leak)

Set max_memory_mb in the config to auto-restart when memory exceeds limit (requires superlance plugin):

# Or set restart based on job count (for Laravel queue)
command=php artisan queue:work --max-jobs=500  # restart after 500 jobs
# Or
command=php artisan queue:work --max-time=3600  # restart every 1 hour

Process doesn't stop gracefully

The signal sent when stopping is TERM by default. Some processes require a different signal:

[program:myworker]
...
stopsignal=INT    # Send SIGINT (Ctrl+C) instead of SIGTERM
stopwaitsecs=60   # Wait 60 seconds before SIGKILL

Frequently Asked Questions

How is Supervisor different from systemd? Which should I use?

systemd is Linux' init system and works with any service. Supervisor is a Python application best suited for managing multiple similar processes (like multiple worker copies) with simpler configuration than systemd. For single main services, systemd is better. For worker pools, Supervisor is more convenient.

How quickly does Supervisor detect a process crash?

Supervisor monitors using an event loop that detects process exit immediately (no polling needed). So restart happens almost instantly, within 1-2 seconds.

How do I restart Supervisor processes after deploying new code?

For queue workers, always restart after deploy since old code still loads in memory. Add this to your deploy script: supervisorctl restart laravel-worker:*. Or for Laravel, use php artisan queue:restart and Supervisor will detect the worker exit and restart automatically.