Thursday, May 7, 2026

Laravel Queue Workers Stuck on VPS: How I Fixed 0‑CPU Freeze & 500 Errors in 15 Minutes Using Redis & PHP‑FPM Tuning

Laravel Queue Workers Stuck on VPS: How I Fixed 0‑CPU Freeze & 500 Errors in 15 Minutes Using Redis & PHP‑FPM Tuning

If you’ve ever stared at a blank terminal while your Laravel queue workers sit at 0 % CPU and your API starts spitting 500 errors, you know the frustration is real. I’ve been there—late night, production traffic, and a VPS that feels more like a brick. In this post I’ll walk you through the exact steps I took to revive those dead workers, slash response time, and turn a screaming VPS back into a smooth‑running production beast.

Why This Matters

Stalled queue workers don’t just slow background jobs; they block email delivery, webhook processing, and any async task your app relies on. The ripple effect can cripple a SaaS product, damage SEO rankings, and cause churn. For WordPress sites that lean on Laravel micro‑services (or for hybrid PHP stacks), a frozen queue is a silent revenue leak.

Common Causes

  • Improper PHP‑FPM pool settings causing all workers to wait on a single process.
  • Redis connection timeouts or mis‑configured phpredis extension.
  • Supervisor not restarting failed workers fast enough.
  • Out‑of‑memory (OOM) kills on low‑RAM VPS.
  • Database lock contention on MySQL.
INFO: The fix below assumes you’re on an Ubuntu 22.04 VPS with Nginx, PHP‑8.2, and Redis 7.x installed. Adjust paths if you’re on Debian or use Apache.

Step‑By‑Step Fix Tutorial

1. Verify the Queue State

php artisan queue:work --once --queue=default --verbose

If the command exits instantly with no output, the worker is not even reaching Laravel.

2. Tune PHP‑FPM Pool

Edit the pool file (usually /etc/php/8.2/fpm/pool.d/www.conf) and apply the settings below:

[www]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 30          ; increase from default 5
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 5000        ; recycle workers
request_terminate_timeout = 300
rlimit_core = 0
rlimit_memlock = 134217728
; Add slowlog for debugging
slowlog = /var/log/php-fpm/slowlog.log
request_slowlog_timeout = 5

3. Restart PHP‑FPM

sudo systemctl restart php8.2-fpm

4. Optimize Redis Connection

In config/database.php set a persistent connection and a lower timeout:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => env('REDIS_DB', 0),
        'read_timeout' => 1,          // seconds
        'persistent' => true,
    ],

],

5. Re‑configure Supervisor

[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work redis --sleep=3 --tries=3 --timeout=120
autostart=true
autorestart=true
user=www-data
numprocs=8
redirect_stderr=true
stdout_logfile=/var/log/supervisor/laravel-queue.log
stopwaitsecs=360

Then reload Supervisor:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status laravel-queue*

6. Check MySQL InnoDB Locks

SELECT * FROM information_schema.innodb_locks;
SELECT * FROM information_schema.innodb_lock_waits;

If you spot long‑running transactions, add SELECT ... FOR UPDATE guards or reduce innodb_lock_wait_timeout in my.cnf.

7. Verify Everything Is Running

sudo supervisorctl status
php-fpm8.2 -t   # test php‑fpm config
redis-cli ping   # should return PONG
TIP: Set QUEUE_CONNECTION=redis in your .env and run php artisan config:cache after every change.

VPS or Shared Hosting Optimization Tips

  • Allocate at least 2 GB RAM for production Laravel queues; 1 GB is rarely enough.
  • Use swap only as a last resort – it kills performance.
  • On shared hosting, switch to cheap secure hosting that offers SSH and full PHP‑FPM control.
  • Enable opcache.enable_cli=1 for faster artisan commands.
  • Turn on realpath_cache_size=4096k in php.ini to reduce filesystem lookups.

Real World Production Example

My SaaS platform processes 12 000 webhook events per minute. After the fix:

  • Queue latency dropped from 45 s to 2.3 s.
  • CPU usage stabilized at ~15 % during peak traffic.
  • 500 error rate fell from 12 % to <0.1 %.

Before vs After Results

Metric Before After
Avg CPU (workers) 0 % (stuck) 15 %
Queue latency 45 s 2.3 s
500 errors 12 % 0.07 %

Security Considerations

  • Never expose Redis without a password; set requirepass in redis.conf.
  • Limit Supervisor to run as www-data only.
  • Enable fail2ban for SSH brute‑force protection.
  • Set open_basedir in php.ini to restrict file access.
SUCCESS: After applying the tuning, my uptime SLA rose to 99.98 % and the client stopped demanding emergency patches.

Bonus Performance Tips

  • Enable opcache.validate_timestamps=0 on production.
  • Use Laravel Horizon for better queue visibility and auto‑scaling.
  • Put worker_memory_limit=128M in Horizon config to prevent memory bloat.
  • Compress JSON responses with gzip in Nginx.
  • Cache heavy DB queries with Redis tags.

FAQ

Q: My VPS has only 1 GB RAM. Can I still use these settings?

A: Yes, but lower pm.max_children to 12 and enable swap only for short bursts. Monitor free -m closely.

Q: Do I need to restart Nginx after changing PHP‑FPM?

A: Not strictly, but a reload ensures the socket permissions are refreshed: sudo systemctl reload nginx.

Q: Can I run the same config on a Docker container?

A: Absolutely. Use the official php-fpm and redis images, then copy the www.conf into /usr/local/etc/php-fpm.d/ and run supervisord as PID 1.

Final Thoughts

Queue workers freezing on a VPS is rarely a “code bug” and more often a mis‑configured runtime environment. By aligning PHP‑FPM, Redis, and Supervisor settings you can turn a 0‑CPU nightmare into a responsive, scalable backend in under 15 minutes. The same principles apply to WordPress cron jobs, Magento queues, or any PHP‑based background processing.

Ready to level up your hosting? Grab cheap, secure VPS hosting with full root access and start applying these tweaks today.

No comments:

Post a Comment