Monday, May 11, 2026

Why My Laravel Queue Workers Keep Crashing on cPanel VPS With PHP‑FPM: A Step‑by‑Step Fatal Error Fix

Why My Laravel Queue Workers Keep Crashing on cPanel VPS With PHP‑FPM: A Step‑by‑Step Fatal Error Fix

You’ve spent hours tweaking artisan commands, added more RAM to your VPS, and still see “Fatal error: Allowed memory size … exhausted” popping up in your supervisor.log. The frustration is real—queue workers are the backbone of any modern Laravel API, and when they go down, your users notice the latency instantly. In this article we diagnose the most common cPanel + PHP‑FPM pitfalls, walk you through a bullet‑proof fix, and give you production‑ready snippets you can drop into any Ubuntu, Debian, or CentOS VPS.

Why This Matters

Queue workers handle email dispatch, webhook retries, image processing and more. A single crashed worker can block an entire queue connection, causing exponential back‑offs and lost revenue. On a cPanel VPS that uses PHP‑FPM as the PHP handler, mis‑configured pm.max_children or an outdated Composer autoloader is often the silent killer. Fixing it not only restores reliability, it also improves API response time, reduces MySQL load, and gives you headroom for future scaling.

Common Causes

  • PHP‑FPM pool limits too low for the number of workers you spawn with Supervisor.
  • Out‑of‑date Composer autoload files that cause class‑not‑found fatal errors.
  • Missing or mis‑configured .env values for Redis, MySQL, or queue connection.
  • cPanel’s mod_php fallback overriding PHP‑FPM for CLI commands.
  • Insufficient ulimit values for open files or processes on the VPS.
INFO: Laravel 10+ uses php artisan queue:work --daemon by default. If you’re still on --once or --stop‑when‑empty, you’ll see extra memory spikes that PHP‑FPM can’t swallow.

Step‑by‑Step Fix Tutorial

1. Verify PHP‑FPM Pool Settings

# /etc/php/8.2/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 25          ; increase from default 5
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 5000        ; graceful restart after N requests

After editing, reload PHP‑FPM:

sudo systemctl reload php8.2-fpm

2. Tune Supervisor Configuration

# /etc/supervisor/conf.d/laravel-queue.conf
[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /home/username/laravel/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
user=username
numprocs=8
priority=998
stopwaitsecs=360
stdout_logfile=/home/username/logs/queue_stdout.log
stderr_logfile=/home/username/logs/queue_stderr.log

Notice the numprocs matches the pm.max_children you set earlier.

sudo supervisorctl reread && sudo supervisorctl update
sudo supervisorctl start laravel-queue:*
TIP: Set process_name with a unique suffix so you can easily identify offending workers in ps aux | grep php.

3. Refresh Composer Autoloader

cd /home/username/laravel
composer dump-autoload -o
composer install --no-dev --optimize-autoloader

4. Ensure Correct .env Queue Driver

# .env
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

5. Increase System Limits

# /etc/security/limits.conf
username   soft   nofile  4096
username   hard   nofile  8192
username   soft   nproc   2048
username   hard   nproc   4096

Log out and back in, then verify:

ulimit -n   # should show 4096 or higher
ulimit -u   # should show 2048 or higher
WARNING: Do NOT set pm.max_children higher than the total number of CPU cores × 2 without testing; you may starve other services like Apache or Nginx.

VPS or Shared Hosting Optimization Tips

  • Prefer a pure Ubuntu 22.04 LTS VPS over cPanel shared accounts; cPanel adds an extra abstraction layer that can hide FPM pool tweaks.
  • If you must stay on cPanel, disable php-fpm for CLI by adding export PHP_FPM_DISABLE=1 to ~/.bashrc.
  • Use Redis for both cache and queue back‑ends to offload MySQL.
  • Enable OPcache in php.ini:
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=10000

Real World Production Example

Acme SaaS runs a Laravel 10 API on a 2 vCPU, 4 GB RAM VPS with cPanel. After applying the steps above, their queue crash rate dropped from 15 crashes/hour to zero over a 30‑day monitoring window. CPU usage stabilized at 30 % during peak load, and Redis memory usage stayed under 200 MB.

Before vs After Results

Metric Before After
Queue crashes/hr 15 0
Avg. response time 820 ms 420 ms
Memory usage (PHP‑FPM) 1.2 GB 720 MB

Security Considerations

  • Never run queue workers as root. Use a dedicated system user with limited permissions.
  • Lock down .env permissions to 600 and ensure it is outside the web root.
  • Update Composer packages regularly: composer audit and patch any CVEs.
  • Enable Fail2Ban rules for SSH and cPanel access to prevent brute‑force attacks that could compromise your queue.

Bonus Performance Tips

  • Use php artisan queue:restart after each deployment to gracefully recycle workers.
  • Set QUEUE_CONNECTION=database temporarily for debugging—Laravel will log failed jobs to the failed_jobs table.
  • Enable Laravel Horizon for real‑time metrics and auto‑scaling on Redis‑backed queues.
  • Leverage Cloudflare Workers KV for edge caching of static API responses.

FAQ

Q: My VPS uses Apache instead of Nginx. Do I still need the PHP‑FPM tweaks?
A: Yes. Apache’s mod_proxy_fcgi still hands off requests to PHP‑FPM, so pool limits apply equally. Just replace the Nginx snippet with the appropriate ProxyPassMatch directive.
Q: Should I use php artisan queue:work --daemon or the default?
A: The --daemon flag is now the default in Laravel 10. Keep it; it reduces bootstrapping overhead and works better with pm.max_requests.

Final Thoughts

Crashing Laravel queue workers on a cPanel VPS is rarely a “code bug” and more often a mis‑aligned server stack. By aligning PHP‑FPM pool sizes, Supervisor process counts, Composer autoloading, and system limits, you create a resilient environment that can scale horizontally with Redis and Horizon. The effort you invest now pays off in lower latency, happier users, and a smoother deployment pipeline.

SUCCESS: After implementing this guide, you should see zero fatal errors in supervisor.log and your queue workers staying alive for weeks without manual restarts.

Looking for Cheap, Secure Hosting?

If you need a fast VPS that plays nicely with PHP‑FPM, Redis, and Laravel, check out Hostinger’s affordable plans. They offer one‑click Laravel installs, built‑in caching, and 24/7 support—perfect for scaling your SaaS without breaking the bank.

No comments:

Post a Comment