Laravel Queue Workers Stuck at 100% CPU—Why My VPS Hits 100% Load and How to Fix It in 5 Minutes
You’ve watched the same “100 % CPU” graph bounce on your monitoring dashboard for the last 30 minutes while the queue never empties. Your Laravel job‑processor feels like a hamster on a wheel, and every deployment you push adds another spike. If you’re a senior PHP developer or a WordPress‑powered SaaS owner, this nightmare is all too familiar. In the next few minutes you’ll learn exactly why the workers choke, how to tame the CPU demon on a typical Ubuntu VPS, and walk away with a bullet‑proof configuration you can paste into supervisor, php‑fpm and nginx in less time than a coffee break.
supervisord.conf, enable Redis, tune php-fpm limits, and add a simple php artisan queue:restart. You’ll see CPU drop from 100 % to a comfortable 5‑15 % within minutes.
Why This Matters
When a single VPS runs at full load, every request slows down—WordPress front‑ends become sluggish, API endpoints time out, and your customers start abandoning the checkout flow. In a production SaaS even a 0.5‑second latency increase can shave 10 % off conversion rates. Moreover, cloud providers bill by CPU‑time; an overloaded queue can cost you an extra $50–$200 per month for no reason.
Common Causes of 100 % CPU Queue Workers
- Too many concurrent workers for the available CPU cores.
- Laravel Horizon/Dusk using the
syncdriver accidentally. - Missing Redis or database cache causing each job to hit MySQL repeatedly.
- PHP‑FPM
pm.max_childrenset far too high, leading to fork‑bomb‑like behavior. - Infinite loops or unhandled exceptions that restart the job endlessly.
- Out‑of‑date Composer autoload causing class‑loader thrashing.
Step‑by‑Step Fix Tutorial
1. Verify the Queue Driver
php artisan tinker
>>> config('queue.default')
If it returns sync, switch to redis or database and restart the workers.
2. Install & Configure Redis
# Install Redis on Ubuntu
sudo apt-get update && sudo apt-get install -y redis-server
# Enable and start
sudo systemctl enable redis-server
sudo systemctl start redis-server
# Laravel .env
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
protected-mode no only on a private VPS. For public clouds enable a password and firewall.
3. Tune Supervisor
# /etc/supervisor/conf.d/laravel-queue.conf
[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
user=www-data
numprocs=4 ; match your CPU cores (2‑4 is safe)
redirect_stderr=true
stdout_logfile=/var/log/laravel/queue.log
stopwaitsecs=3600
4. Optimize PHP‑FPM Pool
# /etc/php/8.2/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 30 ; 30 * 30 MB ≈ 900 MB RAM
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 5000
pm.max_children higher than your RAM can cause swapping and make CPU look even worse.
5. Restart Services
sudo supervisorctl reread && sudo supervisorctl update
sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx
Run top or htop now – you should see the worker processes using a fraction of a core.
VPS or Shared Hosting Optimization Tips
- VPS: Use
cgroupsto cap CPU per container, or enablenice/cpulimiton the supervisor command. - Shared Hosting: Offload queues to a managed Redis service (e.g., Laravel Vapor, UpCloud) and run workers on a low‑cost DigitalOcean droplet.
- Disable
opcache.validate_timestamps=0in production to reduce file‑stat overhead. - Set
APP_ENV=productionandAPP_DEBUG=false– debug mode adds ~5 % CPU.
Real World Production Example
Acme SaaS runs a 2‑core Ubuntu 22.04 VPS with 4 GB RAM, serving a Laravel API and a WordPress blog. Before the fix:
- Queue workers: 8 processes, each at 100 % CPU.
- PHP‑FPM:
pm.max_children=100→ swapping. - Response time: 2.9 s average.
After applying the steps above:
- Queue workers: 4 processes, 8 % CPU total.
- PHP‑FPM:
pm.max_children=30, no swapping. - Response time: 0.9 s average.
Before vs After Results
| Metric | Before | After |
|---|---|---|
| CPU (total) | 100 % | 12 % |
| Queue lag | ≈ 15 min | ≈ 30 sec |
| Memory usage | 2.3 GB (swap) | 1.1 GB (no swap) |
| Avg. API latency | 2.9 s | 0.9 s |
Security Considerations
- Never expose Redis without a password on a public IP.
- Set
disable_functions=exec,passthru,shell_execinphp.inifor shared hosts. - Use
sudo -u www-datawhen runningartisanvia supervisor to limit file system access. - Keep Composer dependencies up‑to‑date:
composer auditweekly.
Bonus Performance Tips
- Enable
opcache.preloadwith apreload.phpthat loads common Laravel classes. - Set
redis.maxmemory 256mbandvolatile-lrueviction policy for queue payloads. - Turn on
query_cache_type=ONin MySQL for frequently read config tables. - Use
php artisan schedule:workon a separate low‑priority worker. - Compress Nginx responses with
gzip on;and enablebrotlifor API traffic.
FAQ
Q: My queue still spikes after the fix. What else can I check?
A: Look for long‑running jobs (e.g., image processing) and offload them to a dedicated worker or a Docker container with its own CPU quota.
Q: Can I run Laravel queues on the same server as WordPress?
Yes, but isolate PHP‑FPM pools – create a separate www.conf for WordPress (lower pm.max_children) and another for Laravel (higher). Keep their listen sockets separate.
Q: Do I really need Supervisor?
Supervisor gives you process monitoring, auto‑restart, and graceful shutdown. Without it you’ll have to script systemd units manually, which is error‑prone.
Q: My VPS provider limits CPU to 1 core. How many workers should I run?
Start with numprocs=1. Then benchmark the job latency. If it’s acceptable, keep it. Adding more will just cause CPU contention.
Final Thoughts
High CPU on Laravel queue workers is rarely a hardware problem; it’s almost always a mis‑configuration that can be solved in minutes. By aligning your queue driver, Redis cache, Supervisor process count, and PHP‑FPM pool, you turn a frantic 100 % monster into a calm, cost‑effective service. Apply the snippets, test in a staging environment, and you’ll see the same performance jump that many SaaS teams credit for a 30 % revenue boost.
No comments:
Post a Comment