Laravel 10 Queue Worker Crashing on cPanel VPS: 5‑Minute Fix for File Permission 777, MySQL Timeouts, and PHP FPM FastCGI Errors
Ever watched a queue worker die after the first job and wondered if the whole server is cursed? You’re not alone. In a production Laravel app hosted on a cheap cPanel VPS, the queue:work command can explode with “Permission denied”, “MySQL has gone away”, or “FastCGI: can't connect to PHP‑FPM” errors. The good news? A handful of command‑line tweaks and config tweaks can resurrect the worker in under five minutes.
Why This Matters
Queue workers are the heartbeat of any modern SaaS, handling email dispatch, webhook retries, image processing, and more. When they crash:
- Customer emails go stale.
- Webhooks time out, breaking API integrations.
- CPU spikes as Supervisor constantly respawns dead processes.
- Revenue loss – every delayed job is a potential sale.
Getting them stable on a shared‑hosting‑style VPS keeps costs low while maintaining the reliability expected from a cloud‑grade platform.
Common Causes on cPanel VPS
- File permissions set to 777 – opens a security hole and confuses PHP‑FPM’s security sandbox.
- MySQL wait_timeout / max_allowed_packet – long‑running jobs hold DB connections too long.
- PHP‑FPM pool limits – default
pm.max_childrenis often 5, not enough for bursty queue traffic. - FastCGI socket path mismatches – Apache or Nginx points to a non‑existent
.sockfile. - Supervisor misconfiguration – wrong user, environment, or autorestart settings.
Step‑by‑Step Fix Tutorial
1. Correct File Permissions (Never 777)
Set the Laravel storage and cache directories to 775 and ensure the owner is the same user Apache/Nginx runs as (usually cpaneluser or www-data).
cd /home/username/public_html
sudo chown -R username:username .
sudo find . -type d -exec chmod 775 {} \;
sudo find . -type f -exec chmod 664 {} \;
# Exempt .env from group‑write
chmod 640 .env
2. Tune MySQL for Long‑Running Jobs
These changes survive a server reboot if you add them to /etc/mysql/conf.d/laravel.cnf.
[mysqld]
wait_timeout = 3600
interactive_timeout = 3600
max_allowed_packet = 64M
Restart MySQL:
sudo systemctl restart mysql
3. Adjust PHP‑FPM Pool Settings
Locate the pool config, usually /etc/php/8.2/fpm/pool.d/www.conf on Ubuntu.
pm = dynamic
pm.max_children = 25
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
; Ensure the socket matches your web server config
listen = /var/run/php/php8.2-fpm.sock
listen.owner = username
listen.group = username
listen.mode = 0660
Restart PHP‑FPM:
sudo systemctl restart php8.2-fpm
4. Align FastCGI Socket with Apache/Nginx
For Apache (mod_proxy_fcgi):
ProxyPassMatch ^/(.*\.php)$ unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost/home/username/public_html
For Nginx:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
5. Configure Supervisor Properly
Supervisor runs the queue worker as the same user that owns the code.
[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /home/username/public_html/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
user=username
numprocs=3
redirect_stderr=true
stdout_logfile=/home/username/logs/queue-worker.log
stopwaitsecs=360
Reload Supervisor:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status laravel-queue*
VPS or Shared Hosting Optimization Tips
- Enable Redis cache for queue back‑ends and session storage.
composer require predis/predis # .env CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=redis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 - Use OPcache – ensure
opcache.enable=1inphp.ini. - Limit cron frequency – replace
php artisan schedule:runevery minute withsystemctl enable laravel-scheduler.timer. - Configure Cloudflare Page Rules to bypass caching for
/api/*and/queue/*routes.
Real World Production Example
Acme SaaS runs on a 2 vCPU Ubuntu 22.04 VPS with 4 GB RAM. Before the fix:
- Queue workers crashed after 7 minutes (MySQL timeout).
- Log files filled with “Permission denied” warnings.
- CPU spiked to 95 % during peak email campaigns.
After applying the steps above, the same workload handled 12 k jobs per hour with CPU 22 % and zero crashes.
Before vs After Results
| Metric | Before | After |
|---|---|---|
| Queue Crash Rate | 78 % | 0 % |
| Avg Job Time | 9 s | 4.2 s |
| CPU Utilization | 95 % | 22 % |
Security Considerations
Never leave directories at 777. It invites ransomware and automated exploits. Keep .env out of web root or protect it with nginx deny all; directives.
- Use
chmod 640 .envandchown root:username .env. - Enable
fail2banfor SSH brute‑force protection. - Set
open_basedirinphp.inito limit file access.
Bonus Performance Tips
- Batch DB writes – use
DB::transaction()or chunked inserts. - Reduce job payload – store only IDs in the queue, fetch models inside the worker.
- Leverage Horizon – it gives you a beautiful dashboard and auto‑scales workers on demand.
- Compress static assets –
npm run prodand enablegzipin Nginx.
FAQ
Q: My queue still restarts after 15 minutes. What’s wrong?
A: Check the supervisor
stopwaitsecsand the Laravel--timeoutflag. Both must be higher than your longest job.
Q: Can I run queues on a shared cPanel account?
A: Yes, but you need to use the
php artisan queue:work --oncepattern with a cron that triggers every minute, or upgrade to a VPS for true daemons.
Final Thoughts
Queue reliability doesn’t have to be a luxury reserved for $200/month cloud instances. By fixing permissions, tuning MySQL, aligning PHP‑FPM sockets, and configuring Supervisor correctly, you restore stability in minutes and keep your VPS cost‑effective. Apply these steps, monitor logs, and you’ll see your Laravel 10 app process jobs like a well‑oiled machine.
Looking for a cheap, secure VPS that ships with all the extensions Laravel loves? Check out Hostinger’s managed PHP hosting – optimized for Laravel, WordPress, and high‑performance queue workers.
No comments:
Post a Comment