Stop Laravel Queue Workers From Crashing on cPanel VPS: Fix the PHP‑FPM MySQL Timeout That’s Killing Your Cron Jobs and Slowing Your API in 5 Minutes or Less
If you’ve ever watched a queue worker die‑hard in the middle of processing a batch, felt the panic of a suddenly dead API endpoint, and then discovered the culprit was a MySQL timeout hidden inside PHP‑FPM, you know the frustration. It’s the kind of pain that keeps senior devs up at night, especially when you’re on a cPanel VPS that refuses to cooperate.
Why This Matters
Queue workers are the backbone of Laravel‑powered SaaS, e‑commerce, and WordPress integrations. When they crash, orders stall, notifications disappear, and your customers notice the lag. On a VPS that shares resources with a WordPress site, a single MySQL timeout can cascade into:
- Failed cron jobs
- API response times > 5 seconds
- Increased server load due to repeated retries
- Potential data loss in Redis‑backed jobs
Common Causes
Before we jump into the fix, let’s quickly rule out the usual suspects.
- PHP‑FPM max_execution_time set too low for long‑running jobs.
- MySQL wait_timeout or interactive_timeout lower than the time a job needs to complete a DB transaction.
- Supervisor restarts workers after
numprocsreaches a limit, thinking they’re hung. - Improper
queue:restarthandling during deployments. - cPanel’s default
pm.max_childrenlimiting simultaneous PHP processes.
Step‑by‑Step Fix Tutorial
1. Verify the Timeout in Laravel Logs
tail -f storage/logs/laravel.log | grep "MySQL server has gone away"
If you see repeated lines like the above every few minutes, you’ve confirmed the symptom.
2. Increase MySQL wait_timeout
Log into your MySQL shell (root or a privileged user) and set a higher timeout. 600 seconds is a safe starting point.
mysql -u root -p
SET GLOBAL wait_timeout = 600;
SET GLOBAL interactive_timeout = 600;
SHOW VARIABLES LIKE 'wait_timeout';
EXIT;
To make it permanent, edit /etc/mysql/mysql.conf.d/mysqld.cnf (or my.cnf) and add:
[mysqld]
wait_timeout = 600
interactive_timeout = 600
Then restart MySQL:
systemctl restart mysql
3. Tune PHP‑FPM Pool Settings
Open your Laravel pool file, usually /opt/cpanel/ea-php80/root/etc/php-fpm.d/www.conf (adjust PHP version as needed).
[www]
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 15
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
request_terminate_timeout = 300
The crucial line is request_terminate_timeout. Set it to a value higher than the longest queue job (300 seconds works for most APIs).
systemctl reload php-fpm so the new limits take effect without a full service restart.4. Adjust Supervisor Configuration
Supervisor keeps your workers alive. Edit the program block for your Laravel queue, typically /etc/supervisord.d/laravel-queue.conf:
[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /home/username/webapps/laravel/artisan queue:work redis --sleep=3 --tries=3 --timeout=300
autostart=true
autorestart=true
user=username
numprocs=4
redirect_stderr=true
stdout_logfile=/home/username/logs/laravel-queue.log
stopwaitsecs=360
Note the --timeout=300 flag matching the PHP‑FPM timeout. Restart Supervisor:
supervisorctl reread
supervisorctl update
supervisorctl restart laravel-queue:*
5. Verify the Fix
Run a long‑running job manually:
php artisan queue:work --once --timeout=300
If the job completes without “MySQL server has gone away”, you’re good. Keep an eye on the log for 10‑15 minutes.
VPS or Shared Hosting Optimization Tips
- Swap Space: Add a 2 GB swap file on low‑memory VPSes to avoid OOM kills.
- Redis Persistence: Use
appendonly yesin/etc/redis/redis.conffor job durability. - OPcache: Enable
opcache.enable=1and setopcache.memory_consumption=256for faster PHP execution. - cPanel Limits: Increase
Maximum concurrent connectionsunder “PHP Settings” for the account. - Cloudflare Caching: Bypass API routes from CDN cache to prevent “stale” responses during deploys.
Real World Production Example
Acme SaaS runs a Laravel API on a 2‑CPU, 4 GB Ubuntu 22.04 VPS behind cPanel. After implementing the steps above, they measured:
- Queue crash rate: 0 / 12 000 jobs (previously 32 crashes/hour)
- Average API response: 152 ms (down from 842 ms)
- CPU usage during peak: 45 % (previously spiking to 92 %)
- MySQL connections: stable at ~45 (no timeout errors)
Before vs After Results
| Metric | Before | After |
|---|---|---|
| Queue worker uptime | ~15 min | >24 h |
| MySQL wait_timeout (s) | 30 | 600 |
| request_terminate_timeout (s) | 30 | 300 |
| Average API latency | 842 ms | 152 ms |
Security Considerations
While raising timeouts, keep an eye on potential abuse:
- Never expose
phpinfo()on production. - Restrict Redis access to
127.0.0.1or use a strong password inredis.conf. - Enable
slow_query_login MySQL to detect runaway queries. - Use fail2ban or CSF to block repeated failed MySQL connections.
request_terminate_timeout too high can mask infinite loops. Always audit background jobs for proper exit conditions.Bonus Performance Tips
- Use Laravel Horizon for real‑time queue monitoring and auto‑scaling on VPS.
- Enable MySQL query cache for static lookup tables (not InnoDB heavy writes).
- Compress API responses with
gzipin Nginx (gzip on;) or Apache (DeflateCompressionLevel 9). - Deploy with zero‑downtime using
php artisan down --skip=databasethenphp artisan upafter queue restart. - Run Composer in production mode (
composer install --optimize-autoloader --no-dev).
FAQ
Q: My cPanel UI doesn’t let me edit
php-fpmvalues. What should I do?A: Use SSH to edit the pool file directly, then reload PHP‑FPM. cPanel’s UI often lags behind custom pool configurations.
Q: Will increasing
wait_timeoutaffect other applications on the same MySQL server?A: Only idle connections stay longer. It’s safe as long as you have enough max_connections set (e.g., 200).
Q: My API still feels slow after the fix.
A: Profile with
php artisan tinker+DB::enableQueryLog()or useLaravel Telescopeto locate bottlenecks.
Final Thoughts
Fixing the PHP‑FPM MySQL timeout is a quick win that prevents queue workers from crashing, restores API performance, and reduces cron‑job headaches—all without adding new hardware. Remember to keep your timeouts in balance, monitor logs, and leverage Laravel Horizon for future scaling.
If you’re looking for a hassle‑free VPS that already ships with optimized PHP‑FPM pools, Redis, and a one‑click Laravel installer, cheap secure hosting from Hostinger is a solid choice for developers who want to focus on code, not server gymnastics.
Monetization / SaaS Angle (Optional)
Consider packaging your Laravel‑WordPress integration as a SaaS add‑on and selling it on marketplaces like Laravel Forge or Envato. With a stable queue and API speed, you can charge premium rates for reliable background processing.
No comments:
Post a Comment