Laravel Worker Queue Crashes on VPS: 7 Proven Fixes to Stop MySQL Timeouts and Redis Latency in 24 Hours
You’ve just pushed a new release, the queue workers spin up, and—boom—everything stalls. Jobs disappear, MySQL throws “Lost connection” errors, and Redis latency spikes like a malfunctioning heart monitor. It’s the kind of frustration that makes seasoned devs want to pull their hair out.
Why This Matters
When a Laravel queue crashes, it’s not just a single endpoint that suffers. API responses lag, email notifications stop, and any WordPress plugin that relies on the same Redis cache inherits the slowdown. For SaaS businesses, that translates directly into lost revenue and angry customers.
Common Causes
- MySQL wait_timeout < 1800 seconds causing dropped connections.
- Redis maxmemory‑policy set to “noeviction” and a burst of jobs fills the cache.
- Supervisor not restarting workers fast enough.
- PHP‑FPM children limit too low for the queue load.
- Improper Nginx fastcgi buffers leading to 504 Gateway Timeouts.
- Composer autoload optimization missing on production.
- Docker or VPS resource throttling (CPU/IO) during peak traffic.
Step‑by‑Step Fix Tutorial
1. Tune MySQL Session Settings
-- /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
wait_timeout = 28800
interactive_timeout = 28800
max_allowed_packet = 64M
innodb_flush_log_at_trx_commit = 2 # safe for most SaaS workloads
Restart MySQL and confirm the new values:
sudo systemctl restart mysql
mysql -e "SHOW VARIABLES LIKE 'wait_timeout';"
2. Optimize Redis Memory Policy
# /etc/redis/redis.conf
maxmemory 2gb
maxmemory-policy allkeys-lru
tcp-keepalive 60
3. Configure Supervisor for Laravel Queues
# /etc/supervisor/conf.d/laravel-queue.conf
[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/laravel/queue.log
stopwaitsecs=360
After editing, run:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status laravel-queue*
4. Raise PHP‑FPM Workers
# /etc/php/8.2/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
request_terminate_timeout = 300
5. Adjust Nginx FastCGI Buffers
# /etc/nginx/sites-available/laravel.conf
server {
listen 80;
server_name app.example.com;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_buffer_size 16k;
fastcgi_buffers 8 16k;
fastcgi_busy_buffers_size 32k;
fastcgi_temp_file_write_size 64k;
fastcgi_read_timeout 300;
}
}
6. Run Composer Optimizations
composer install --optimize-autoloader --no-dev
php artisan config:cache
php artisan route:cache
php artisan view:cache
7. Enable Linux IO Scheduler & Swap (VPS only)
# Verify current scheduler
cat /sys/block/sda/queue/scheduler
# Set to deadline (better for DB workloads)
echo deadline | sudo tee /sys/block/sda/queue/scheduler
# Add 2GB swap if memory is tight
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
htop, redis-cli info, and mysqladmin status for at least 10 minutes before moving to the next step.
VPS or Shared Hosting Optimization Tips
- Prefer Ubuntu 22.04 LTS for the latest kernel and security patches.
- If on shared hosting, request increased MySQL wait_timeout and a dedicated Redis instance.
- Use Cloudflare “Cache Everything” for static assets; set
Page Rules → Bypass Cache → /wp‑admin/*to keep admin fast. - Enable HTTP/2 or HTTP/3 on Nginx to reduce latency for API calls.
Real World Production Example
Acme SaaS runs a 12‑node Laravel cluster behind a Load Balancer. Before applying the 7 fixes, queue latency averaged 45 seconds and MySQL hit “Lock wait timeout” errors every 5 minutes. After the changes, the average job completion dropped to 1.8 seconds and Redis memory stayed under 70 % of the allocated 4 GB.
Before vs After Results
| Metric | Before | After |
|---|---|---|
| Avg Queue Time | 45 s | 1.8 s |
| MySQL Timeout Errors | 12 /hr | 0 /hr |
| Redis CPU | 85 % | 42 % |
| PHP‑FPM Workers | 12 busy / 20 max | 38 busy / 50 max |
Security Considerations
Never expose Redis directly to the internet—bind it to 127.0.0.1 or use a VPC firewall. Enable MySQL caching_sha2_password and enforce strong passwords in .env. Keep Composer dependencies up‑to‑date with composer audit and run php artisan schedule:run under a non‑root user.
opcache.validate_timestamps in production is safe only when you deploy with zero‑downtime scripts. Forgetting to clear OPcache after a new release can resurrect old code and cause cryptic errors.
Bonus Performance Tips
- Enable
bytecode cachingwithopcache.enable_cli=1for Artisan commands. - Use
Laravel Horizonto monitor queue health in real time. - Set
queue:retry_afterslightly higher than your longest job (e.g., 300 seconds). - Leverage
php artisan event:cacheto speed up event listeners. - Compress Redis payloads with
msgpackif you’re sending large JSON blobs.
FAQ
Q: My queue still dies after these changes. What next?
A: Check the system dmesg for OOM kills, increaseulimit -nfor open files, and verify Docker cgroup limits if you run inside containers.
Q: Can I use MySQL 8 with Laravel 10?
A: Yes—just setDB_CONNECTION=mysqland use themysql8driver if you need the native JSON functions.
Final Thoughts
Queue crashes are rarely a single‑point failure. By tightening MySQL timeouts, giving Redis breathing room, and scaling PHP‑FPM and Supervisor correctly, you can turn a flaky VPS into a rock‑solid Laravel engine. Apply the seven fixes, monitor the metrics, and you’ll see the difference within a few hours—not days.
Looking for Cheap, Secure Hosting?
Boost your Laravel and WordPress stack on a high‑performance VPS that includes daily backups, DDoS protection, and 24/7 support. Get started with Hostinger now and enjoy a 30‑day money‑back guarantee.
No comments:
Post a Comment