Your Laravel app is slow. Users wait 30 seconds for emails. Orders take forever to process. Your boss is asking questions.
Sound familiar? You're not alone. Most Laravel developers face this exact nightmare until they discover Laravel queues with Supervisor.
Think of queues like a smart waiter in a busy restaurant. Instead of making customers wait while the chef cooks each meal, the waiter takes all orders first, then lets the kitchen work on them one by one. Your users get instant responses while heavy tasks happen behind the scenes.
In this Laravel tutorial, you'll learn how to setup Supervisor to manage your Laravel queues like a pro. No more slow loading times. No more frustrated users. Just smooth, fast apps that work.
What is Laravel Queue and Why You Need It
Laravel queues handle slow tasks in the background. When someone uploads a large file or you need to send 1000 emails, queues move these tasks away from your main app.
Here's what happens without queues:
- User clicks "send email"
- App stops everything to send email
- User waits and waits
- User gets frustrated and leaves
With queues:
- User clicks "send email"
- App says "done!" instantly
- Email gets sent in background
- User stays happy
Common tasks that need queues:
- Sending emails (welcome emails, notifications)
- Processing uploaded files (images, videos, documents)
- Generating reports
- Calling external APIs
- Database cleanups
What is Supervisor and Why Laravel Needs It
Supervisor is like a babysitter for your Laravel queue workers. Queue workers are programs that process your background tasks. But workers can crash, stop working, or run out of memory.
Without Supervisor, if your queue worker dies, your background tasks stop. Emails don't send. Files don't process. Everything breaks.
Supervisor watches your queue workers and:
- Starts workers automatically when server boots
- Restarts workers if they crash
- Runs multiple workers at the same time
- Keeps workers running 24/7
It's like having a security guard that never sleeps, making sure your workers always do their job.
Installing Supervisor on Your Server
First, let's install Supervisor on your Ubuntu server. Open your terminal and run:
sudo apt-get update sudo apt-get install supervisor Check if Supervisor installed correctly:
sudo systemctl status supervisor You should see "active (running)" which means Supervisor is working.
If you're using a different Linux system:
- CentOS/RHEL:Ā
sudo yum install supervisor - Amazon Linux:Ā
sudo yum install supervisor - Debian:Ā
sudo apt install supervisor
Setting Up Laravel Queue Configuration
Before we configure Supervisor, make sure your Laravel queue is ready.
Step 1: Choose Your Queue Driver
Open yourĀ .envĀ file and set your queue driver:
QUEUE_CONNECTION=database You can also use:
redisĀ (faster, needs Redis installed)syncĀ (for testing, runs immediately)sqsĀ (Amazon SQS for production)
Step 2: Create Database Queue Table
If using database driver, create the jobs table:
php artisan queue:table php artisan migrate This creates aĀ jobsĀ table where Laravel stores your queued tasks.
Step 3: Test Your Queue Setup
Create a simple test job:
php artisan make:job TestEmail EditĀ app/Jobs/TestEmail.php:
Dispatch the job in a controller or route:
use App\Jobs\TestEmail; // In a controller method TestEmail::dispatch();
Configuring Supervisor for Laravel Queue
Now comes the important part - telling Supervisor how to manage your Laravel queue workers.
Step 1: Create Supervisor Configuration File
Create a new configuration file:
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
Step 2: Add Configuration Settings
Copy this configuration into the file:
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /path-to-laravel-app/artisan queue:work --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true stopasgroup=true killasgroup=true user=www-data numprocs=8 redirect_stderr=true stdout_logfile=/path-to-laravel-log/worker.log stopwaitsecs=3600
Important:Ā Replace the paths with your actual paths:
/path-to-laravel-app/Ā = your Laravel app directory (likeĀ /var/www/your-app)/path-to-laravel-log/Ā = your log directory (likeĀ /var/www/your-app/storage/logs)user=www-dataĀ = your web server user (might beĀ nginx,Ā apache, or your username)
Step 3: Understanding Each Configuration Option
Let me explain what each setting does:
process_name: Names each worker processcommand: The actual command to run queue workersautostart=true: Start workers when server bootsautorestart=true: Restart workers if they crashstopasgroup=true: Stop all related processes togetherkillasgroup=true: Kill all related processes togetheruser: Which user runs the workersnumprocs=8: Run 8 worker processes (adjust based on your server)redirect_stderr=true: Capture error messagesstdout_logfile: Where to save logsstopwaitsecs=3600: Wait 1 hour before killing workers
Step 4: Optimize Worker Settings
TheĀ --sleep=3 --tries=3 --max-time=3600Ā options are important:
--sleep=3: Wait 3 seconds between checking for new jobs--tries=3: Retry failed jobs 3 times before giving up--max-time=3600: Restart worker after 1 hour (prevents memory leaks)
AdjustĀ numprocsĀ based on your server:
- Small server (1-2 CPU cores): 2-4 workers
- Medium server (4 CPU cores): 4-8 workers
- Large server (8+ CPU cores): 8-16 workers
Starting and Managing Supervisor Workers
Step 1: Load New Configuration
Tell Supervisor about your new configuration:
sudo supervisorctl reread sudo supervisorctl update
Step 2: Start Laravel Workers
Start all your Laravel workers:
sudo supervisorctl start "laravel-worker:*"
Step 3: Check Worker Status
See if your workers are running:
sudo supervisorctl status "laravel-worker:*"
You should see something like:
laravel-worker:laravel-worker_00 RUNNING pid 1234, uptime 0:01:00 laravel-worker:laravel-worker_01 RUNNING pid 1235, uptime 0:01:00 laravel-worker:laravel-worker_02 RUNNING pid 1236, uptime 0:01:00
Common Supervisor Management Commands
Here are the commands you'll use most often:
Check All Workers
sudo supervisorctl status
Stop All Laravel Workers
sudo supervisorctl stop "laravel-worker:*"
Restart All Laravel Workers
sudo supervisorctl restart "laravel-worker:*"
Stop Specific Worker
sudo supervisorctl stop laravel-worker:laravel-worker_00
View Worker Logs
sudo supervisorctl tail laravel-worker:laravel-worker_00
Reload Supervisor Configuration
sudo supervisorctl reread sudo supervisorctl update
Troubleshooting Common Issues
Workers Not Starting
Problem:Ā sudo supervisorctl statusĀ shows workers as "FATAL" or "STOPPED"
Solutions:
- Check file paths in your configuration
- Make sure the user exists and has permissions
- Verify Laravel app works:Ā
php /path-to-laravel-app/artisan queue:work - Check logs:Ā
sudo supervisorctl tail laravel-worker:laravel-worker_00
Permission Errors
Problem: Workers can't write to log files or access Laravel app
Solutions:
- Fix file ownership:Ā
sudo chown -R www-data:www-data /path-to-laravel-app - Fix permissions:Ā
sudo chmod -R 755 /path-to-laravel-app - Create log directory:Ā
mkdir -p /path-to-laravel-log
Workers Consuming Too Much Memory
Problem: Workers use lots of RAM and slow down server
Solutions:
- LowerĀ
numprocsĀ in configuration (fewer workers) - ReduceĀ
--max-timeĀ to restart workers more often - AddĀ
--max-jobs=1000Ā to restart after processing 1000 jobs
Queue Jobs Not Processing
Problem: Jobs stay in queue but never get processed
Solutions:
- Check if workers are running:Ā
sudo supervisorctl status - Restart workers:Ā
sudo supervisorctl restart "laravel-worker:*" - Clear failed jobs:Ā
php artisan queue:flush - Restart queue:Ā
php artisan queue:restart
Monitoring Your Queue Performance
Check Queue Size
See how many jobs are waiting:
php artisan queue:monitor
View Failed Jobs
See jobs that failed:
php artisan queue:failed
Retry Failed Jobs
Retry all failed jobs:
php artisan queue:retry all
Clear All Queued Jobs
Emergency stop - clear everything:
php artisan queue:flush
Advanced Supervisor Configuration
Multiple Queue Priorities
If you have different types of jobs, you can create separate workers for each:
[program:laravel-high-priority] process_name=%(program_name)s_%(process_num)02d command=php /path-to-laravel-app/artisan queue:work --queue=high --sleep=1 --tries=3 user=www-data numprocs=2 autostart=true autorestart=true stdout_logfile=/path-to-laravel-log/high-priority.log [program:laravel-low-priority] process_name=%(program_name)s_%(process_num)02d command=php /path-to-laravel-app/artisan queue:work --queue=low --sleep=5 --tries=1 user=www-data numprocs=1 autostart=true autorestart=true stdout_logfile=/path-to-laravel-log/low-priority.log
Environment-Specific Configuration
For production servers, use stricter settings:
[program:laravel-production] process_name=%(program_name)s_%(process_num)02d command=php /var/www/laravel-app/artisan queue:work --sleep=3 --tries=3 --max-time=1800 --max-jobs=500 autostart=true autorestart=true stopasgroup=true killasgroup=true user=www-data numprocs=4 redirect_stderr=true stdout_logfile=/var/log/laravel/worker.log stopwaitsecs=3600 priority=100
Best Practices for Production
1. Use Environment Variables
Store sensitive config inĀ .envĀ file:
QUEUE_CONNECTION=redis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=your-redis-password REDIS_PORT=6379
2. Set Up Log Rotation
Prevent log files from getting too big:
sudo nano /etc/logrotate.d/laravel-worker
Add:
/var/log/laravel/*.log { daily missingok rotate 14 compress delaycompress notifempty sharedscripts }
3. Monitor Resource Usage
Watch CPU and memory:
htop
Look forĀ php artisan queue:workĀ processes. If they use too much memory, reduceĀ numprocsĀ or lowerĀ --max-time.
4. Set Up Alerts
Use monitoring tools likeĀ New RelicĀ orĀ DataDogĀ to get alerts when:
- Queue size gets too large
- Workers crash repeatedly
- Response times get slow
Testing Your Setup
Create a Test Job
Make a simple job to test everything works:
php artisan make:job SendWelcomeEmail
Edit the job:
userEmail = $userEmail; } public function handle(): void { // Send welcome email Mail::raw('Welcome to our app!', function ($message) { $message->to($this->userEmail) ->subject('Welcome!'); }); } }
Dispatch and Test
In a controller or route:
use App\Jobs\SendWelcomeEmail; SendWelcomeEmail::dispatch('[email protected]');
Check your worker logs to see it processed:
sudo supervisorctl tail laravel-worker:laravel-worker_00
Scaling Your Queue System
When to Add More Workers
Add more workers when:
- Queue size stays high (over 100 jobs)
- Jobs take too long to process
- Users complain about slow emails/notifications
When to Use Redis Instead of Database
Switch to Redis when:
- Processing over 1000 jobs per hour
- Need faster job dispatch
- Want better performance monitoring
Install Redis:
sudo apt-get install redis-server
UpdateĀ .env:
QUEUE_CONNECTION=redis
When to Consider Laravel Horizon
Laravel HorizonĀ provides a dashboard and advanced features for Redis queues. Consider it when:
- Managing multiple queue types
- Need detailed monitoring
- Want automatic worker balancing
- Running large-scale applications
Security Considerations
1. Run Workers as Non-Root User
Never run workers as root. Use www-data or create a dedicated user:
sudo adduser laravel-worker sudo usermod -a -G www-data laravel-worker
2. Limit Worker Permissions
Workers only need access to:
- Laravel application files (read)
- Storage directories (write)
- Log directories (write)
3. Monitor for Suspicious Jobs
Log all job executions and watch for:
- Jobs that take unusually long
- Jobs that fail repeatedly
- Unexpected job types
4. Validate Job Data
Always validate data in your job classes:
public function handle(): void { if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) { throw new InvalidArgumentException('Invalid email address'); } // Process job... }
Real-World Example: E-commerce Order Processing
Here's how a real e-commerce site might use Laravel queues with Supervisor:
Job Types
// Send order confirmation email SendOrderConfirmation::dispatch($order); // Update inventory UpdateInventory::dispatch($order->items); // Process payment ProcessPayment::dispatch($order->payment_details); // Generate invoice PDF GenerateInvoice::dispatch($order);
Supervisor Configuration
[program:ecommerce-orders] process_name=%(program_name)s_%(process_num)02d command=php /var/www/shop/artisan queue:work --queue=orders --sleep=1 --tries=3 --max-time=1800 user=www-data numprocs=4 autostart=true autorestart=true stdout_logfile=/var/log/shop/orders.log [program:ecommerce-emails] process_name=%(program_name)s_%(process_num)02d command=php /var/www/shop/artisan queue:work --queue=emails --sleep=3 --tries=2 --max-time=3600 user=www-data numprocs=2 autostart=true autorestart=true stdout_logfile=/var/log/shop/emails.log
This setup processes orders quickly while keeping email sending separate and stable.
You now have everything you need to setup Laravel queues with Supervisor like a pro. Your users will love the faster response times, and you'll sleep better knowing your background tasks run reliably 24/7.
Start with the basic configuration, test it thoroughly, then optimize based on your app's specific needs. Most importantly, monitor your setup and adjust as your application grows.
Remember: the best queue system is one that works silently in the background while your users enjoy a lightning-fast experience. That's the real power of Laravel queues with Supervisor.
Be the first to show love! š
Start something amazing - your support inspires creators!