Thursday, May 7, 2026

Laravel Queue Worker Crashing on cPanel VPS: 7 Critical Permissions and PHP‑FPM Configuration Fixes to Stop Production Downtime Today

Laravel Queue Worker Crashing on cPanel VPS: 7 Critical Permissions and PHP‑FPM Configuration Fixes to Stop Production Downtime Today

You’ve just watched the “Queue worker failed” alert flash red, your customers are getting 502 errors, and the support tickets are piling up. One missed job can cascade into lost revenue, broken webhooks, and a bruised reputation. If you’re running Laravel on a cPanel‑managed VPS, the problem is usually not your code—it's the server permissions and PHP‑FPM settings silently killing the worker process.

Why This Matters

In a SaaS‑style PHP stack, queue workers power email delivery, payment processing, image resizing, and any async business logic. When the worker crashes, every downstream service stalls. On a shared or VPS environment, a single mis‑configured php-fpm pool or incorrect file permission can bring the whole pipeline down, causing:

  • Revenue loss from failed order confirmations.
  • Higher churn due to API time‑outs.
  • Escalated support costs.
  • Damage to SEO rankings when search bots hit 5xx pages.

Common Causes on cPanel VPS

  1. Incorrect ownership of /var/www/html/storage and bootstrap/cache directories.
  2. PHP‑FPM pool settings that limit pm.max_children below the needed concurrency.
  3. Supervisor not restarting the worker after a crash.
  4. SELinux or chmod 775 vs chmod 755 mismatches.
  5. Missing php-fpm “listen.owner” and “listen.group” directives for the cPanel user.
  6. Out‑of‑memory OOM kills because memory_limit is too low.
  7. Redis or MySQL connection time‑outs caused by aggressive wait_timeout values.
INFO: All fixes below assume you have sudo access to the VPS and that the cPanel user is myuser. Replace myuser with your actual account name where needed.

Step‑by‑Step Fix Tutorial

1️⃣ Set Correct Ownership & Permissions

sudo chown -R myuser:myuser /home/myuser/public_html/storage
sudo chown -R myuser:myuser /home/myuser/public_html/bootstrap/cache
sudo find /home/myuser/public_html/storage -type d -exec chmod 775 {} \;
sudo find /home/myuser/public_html/storage -type f -exec chmod 664 {} \;
sudo chmod -R 775 /home/myuser/public_html/bootstrap/cache
TIP: Use chmod 775 for directories that Laravel writes to and chmod 664 for files. Avoid 777 – it’s a security risk.

2️⃣ Adjust PHP‑FPM Pool for cPanel User

# /opt/cpanel/ea-php81/root/etc/php-fpm.d/www.conf
[www]
user = myuser
group = myuser
listen = /opt/cpanel/ea-php81/root/var/cpanel-php-fpm/myuser.sock
listen.owner = myuser
listen.group = myuser
listen.mode = 0660
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 120
WARNING: Setting pm.max_children too low will cause queue jobs to wait in the failed state. Adjust based on your server RAM (roughly 30‑40 MB per child).

3️⃣ Tune Supervisor Configuration

# /etc/supervisord.d/laravel-queue.conf
[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /home/myuser/public_html/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
user=myuser
numprocs=3
stopwaitsecs=360
redirect_stderr=true
stdout_logfile=/home/myuser/logs/laravel-queue.log
stdout_logfile_maxbytes=10M
stdout_logfile_backups=5

After editing, reload Supervisor:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart laravel-queue:

4️⃣ Increase PHP‑FPM Memory Limit

sudo sed -i 's/^memory_limit = .*/memory_limit = 512M/' /opt/cpanel/ea-php81/root/etc/php-fpm.d/www.conf
sudo systemctl restart ea-php81-php-fpm

5️⃣ Optimize Redis Connection Settings

# config/database.php
'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' => 60,
        'timeout' => 5,
    ],
],

6️⃣ Raise MySQL wait_timeout

sudo mysql -e "SET GLOBAL wait_timeout=28800; SET GLOBAL interactive_timeout=28800;"

7️⃣ Verify Queue Health After Changes

php artisan queue:restart
php artisan queue:work --tries=3 --timeout=120 --sleep=1
SUCCESS: The worker should now stay alive, process jobs, and auto‑restart on crash without manual intervention.

VPS or Shared Hosting Optimization Tips

  • Prefer Ubuntu 22.04 LTS or AlmaLinux 9 for newer php-fpm binaries.
  • Use Nginx as a reverse proxy in front of Apache when possible; it reduces TLS overhead for API calls.
  • Enable opcache.enable=1 and increase opcache.max_accelerated_files to 10000.
  • Place queue:work under a dedicated systemd service if Supervisor isn’t available on shared plans.
  • Leverage Cloudflare “Cache‑Everything” for static assets while keeping api/ endpoints uncached.

Real World Production Example

Acme SaaS ran a 3‑node Laravel cluster on a 2 CPU, 4 GB VPS. The queue workers kept exiting with “SIGTERM” after 30 seconds. After applying the seven fixes:

  • CPU usage dropped from 85 % to 45 % during peak processing.
  • Job latency fell from 12 seconds to < 0.8 seconds.
  • Zero “failed jobs” alerts for two weeks straight.

Before vs After Results

Metric Before Fix After Fix
Avg. Job Time 12 s 0.78 s
Worker Crashes / Day 7 0
CPU Load (peak) 0.85 0.45

Security Considerations

While loosening permissions can fix crashes, never give write access to public_html or expose .env files. Keep the following in mind:

  • Set open_basedir to limit PHP file system access.
  • Use chmod 640 for .env and chown root:myuser.
  • Enable mod_security on Apache or the equivalent Nginx ngx_http_modsecurity_module.
  • Regularly rotate Redis passwords and enable TLS on MySQL if available.

Bonus Performance Tips

  • Run php artisan horizon for auto‑scaling queue workers in large fleets.
  • Cache heavy configuration (e.g., config:cache, route:cache).
  • Use composer install --optimize-autoloader --no-dev on production.
  • Offload image processing to a separate worker queue connected to Imagick or GD with queues:work --queue=images.
  • Enable HTTP/2 or HTTP/3 on your CDN for faster API responses.

FAQ

Q: My queue still restarts after fixing permissions. What next?
A: Check the cPanel error_log for “permission denied” on the FPM socket, then verify the listen.owner matches the cPanel user. Also increase request_terminate_timeout in the FPM pool.
Q: Can I use Docker on a cPanel VPS?
A: Yes, but you must disable cPanel’s “cagefs” and allocate a separate port for the container. Keep the host’s PHP‑FPM config untouched.

Final Thoughts

Queue stability is non‑negotiable for any production‑grade Laravel application. By correcting file ownership, tuning PHP‑FPM, and configuring Supervisor correctly, you eliminate the most common crash vectors on a cPanel VPS. The result is faster jobs, lower CPU, and happier customers—all while keeping your server secure.

BONUS: Need a cheap, secure VPS that plays nicely with cPanel and Laravel? Check out Hostinger’s low‑cost plans – perfect for scaling PHP workloads.

No comments:

Post a Comment