Laravel Queue Workers Stuck on VPS: Fix FastCGI Timeouts, Redis Memory Leaks, and Broken Sleeping Jobs in 5 Minutes
Ever watched a Laravel queue grind to a halt on your VPS and felt the heat rise? You’re not alone. One mis‑configured php‑fpm pool, a greedy Redis instance, or a sleeping job that never wakes can turn a high‑traffic API into a silent killer. This guide shows you how to diagnose and fix those pain points in under five minutes—so your workers keep humming and your users stay happy.
Why This Matters
Queue workers power everything from email dispatch to real‑time notifications. When they stall:
- Customer orders sit in limbo.
- API latency spikes, hurting SEO and conversion.
- Server resources are wasted, raising your VPS bill.
Fixing the root cause not only restores performance but also prevents future outages and protects your brand’s reputation.
Common Causes
- FastCGI timeout – Nginx/Apache gives up on PHP‑FPM after 30 seconds.
- Redis memory leaks – Unlimited
maxmemoryfills RAM, causing the worker to crash. - Sleeping jobs –
queue:work --sleep=3mis‑configured, leading to a deadlock. - Supervisor mis‑restart – Wrong
numprocsorstopwaitsecsvalues.
Step‑By‑Step Fix Tutorial
1️⃣ Diagnose the FastCGI Timeout
Run a quick curl test to see the response time of a simple route.
curl -w "\nTime: %{time_total}s\n" -o /dev/null https://example.com/api/ping
If the time hovers around 30 seconds and ends with a 502, you’ve hit the FastCGI timeout.
2️⃣ Extend PHP‑FPM & Nginx Limits
Update /etc/php/8.2/fpm/pool.d/www.conf (adjust version as needed):
request_terminate_timeout = 120
request_slowlog_timeout = 30
rlimit_cpu = 120
Then adjust Nginx:
http {
fastcgi_read_timeout 120;
fastcgi_send_timeout 120;
}
Reload services:
sudo systemctl restart php8.2-fpm
sudo systemctl reload nginx
3️⃣ Tame Redis Memory
Warning: Setting maxmemory too low can cause job loss. Pick a value that leaves at least 20 % of RAM free.
# Connect to Redis CLI
redis-cli CONFIG SET maxmemory 256mb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
4️⃣ Fix Sleeping Jobs
Instead of --sleep=3, let Supervisor handle back‑off.
# /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 --tries=3 --timeout=90
autostart=true
autorestart=true
numprocs=4
startsecs=5
stopwaitsecs=300
stdout_logfile=/var/log/laravel/queue.log
stderr_logfile=/var/log/laravel/queue_error.log
Reload Supervisor:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart laravel-queue:*
5️⃣ Verify Everything
# Check queue health
php artisan queue:listen --once
# Verify Redis memory
redis-cli INFO memory | grep used_memory_human
If no errors appear and jobs pop off the queue, you’re good to go.
VPS or Shared Hosting Optimization Tips
- Enable
opcacheinphp.ini(opcache.enable=1,opcache.memory_consumption=256). - Use
systemctl enable php‑fpmto keep PHP alive after reboots. - On shared hosting, replace Supervisor with
cron“every minute” runners, but keep--sleeplow. - Turn on Cloudflare caching for static assets to offload bandwidth.
Real World Production Example
Acme Co. runs a Laravel‑backed SaaS on a 2 vCPU Ubuntu 22.04 VPS. After a Redis memory leak, their queue slowed to 1 job per minute. By applying the steps above, they cut average job latency from 45 seconds to 2.3 seconds and saved $120/month on an upgraded VPS plan.
Before vs After Results
| Metric | Before | After |
|---|---|---|
| Avg. Job Time | 45 s | 2.3 s |
| CPU Spike | 90 % | 30 % |
| Memory Used (Redis) | 1.8 GB | 256 MB |
Security Considerations
- Never expose Redis without a password. Add
requirepass strong‑keytoredis.conf. - Lock down Supervisor config files (chmod 640, owned by
www-data). - Enable
disable_functions=exec,passthru,system,shell_execinphp.inifor shared hosts. - Use UFW or firewalld to restrict port 6379 to localhost only.
Bonus Performance Tips
- Set
QUEUE_CONNECTION=redisandREDIS_CLIENT=phpredisfor native extension speed. - Use
horizondashboards to monitor worker health in real time. - Chunk large payloads with
chunk()to keep memory low. - Deploy zero‑downtime releases with
php artisan down --allow=123.45.67.89for admin IPs.
FAQ
Q: My queue still “stuck” after increasing timeouts. What now?
A: Check the Laravel log (storage/logs/laravel.log) for uncaught exceptions. Often a failing job throws an error that never gets released back to the queue.
Q: Can I run the same config on a Docker container?
Yes. Use the official php:8.2-fpm image, add a custom www.conf, and mount Supervisor config as a volume.
Q: Does this affect WordPress sites on the same VPS?
Adjusting php‑fpm pool limits is safe for WordPress; just ensure each pool has its own pm.max_children based on traffic.
Final Thoughts
Stuck queue workers are rarely a Laravel bug—they’re a server‑side symptom. By tightening FastCGI limits, capping Redis memory, and letting Supervisor manage back‑off, you can turn a flaky VPS into a rock‑solid processing engine in minutes. Keep these snippets handy, automate the config with Ansible or Terraform, and you’ll spend less time firefighting and more time shipping features.
Grab a Fast, Secure VPS & Keep Your Apps Running
Need a reliable, low‑cost VPS that plays nice with Laravel, Redis, and WordPress? Check out cheap secure hosting at Hostinger – the perfect environment for the fixes above.
No comments:
Post a Comment