Monday, May 11, 2026

Laravel Worker Queue Crashes on VPS: 7 Proven Fixes to Stop MySQL Timeouts and Redis Latency in 24 Hours

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

INFO: Use “volatile-lru” if you only cache transient data, otherwise “allkeys-lru” will keep the most used keys alive.
# /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
TIP: After each change, monitor 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.

WARNING: Disabling 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

  1. Enable bytecode caching with opcache.enable_cli=1 for Artisan commands.
  2. Use Laravel Horizon to monitor queue health in real time.
  3. Set queue:retry_after slightly higher than your longest job (e.g., 300 seconds).
  4. Leverage php artisan event:cache to speed up event listeners.
  5. Compress Redis payloads with msgpack if 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, increase ulimit -n for open files, and verify Docker cgroup limits if you run inside containers.
Q: Can I use MySQL 8 with Laravel 10?
A: Yes—just set DB_CONNECTION=mysql and use the mysql8 driver 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.

SUCCESS: With the steps above, most developers eliminate queue timeouts, reduce latency, and free up CPU for new feature work—turning a night‑mare deployment into a smooth release.

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