Saturday, May 9, 2026

Laravel Queue Workers Hang on Shared Hosting: How to Fix the “Connection Refused” Error and Restore Fast, Reliable Background Jobs in 10 Minutes【PHP, FPM, VPS】

Laravel Queue Workers Hang on Shared Hosting: How to Fix the “Connection Refused” Error and Restore Fast, Reliable Background Jobs in 10 Minutes【PHP, FPM, VPS】

You’ve just pushed a new feature, the queue fires, but the workers never finish. Logs scream “Connection refused” and your users stare at a stalled checkout page. It feels like the whole app is grinding to a halt, and you’re stuck on a cheap shared host that promises “unlimited” resources. This article shows you, step‑by‑step, how to diagnose the root cause, re‑configure PHP‑FPM, Supervisor, and Redis, and get your Laravel queues humming again—whether you stay on shared hosting or upgrade to a VPS.

Why This Matters

Background jobs are the backbone of modern SaaS: email newsletters, image processing, payment retries, webhook dispatches. When a queue worker stalls, you lose revenue, damage brand trust, and waste developer time. Fixing the “Connection refused” error not only restores reliability but also opens the door to scaling your Laravel‑WordPress combo sites without hitting the dreaded “500 Internal Server Error” wall.

Common Causes of “Connection Refused” on Shared Hosting

  • Redis or database socket blocked by the host’s firewall.
  • PHP‑FPM pool limits (max_children, pm.max_requests) hitting the shared quota.
  • Supervisor not allowed to run long‑living daemons.
  • Mis‑matched QUEUE_CONNECTION env variable (e.g., set to redis while Redis isn’t reachable).
  • Out‑of‑date Composer autoload causing class‑resolution failures during job dispatch.

Step‑By‑Step Fix Tutorial

1. Verify Network Reachability

# Test Redis connection from the host
redis-cli -h 127.0.0.1 -p 6379 ping
# Expected output: PONG
# If you get “Could not connect to Redis at 127.0.0.1:6379” → firewall issue
INFO: On most shared plans 127.0.0.1 is allowed, but external IPs are blocked. If you need an external Redis, switch to a managed Cloud Redis or upgrade to a VPS.

2. Adjust .env for Localhost Queues

QUEUE_CONNECTION=database
CACHE_DRIVER=file
SESSION_DRIVER=file
# If Redis works, keep redis:
# QUEUE_CONNECTION=redis
# REDIS_HOST=127.0.0.1
# REDIS_PORT=6379

3. Tune PHP‑FPM (for both Apache & Nginx)

Open the pool file (often /etc/php/8.2/fpm/pool.d/www.conf on Ubuntu). Increase limits just enough to stay under the host’s caps.

pm = dynamic
pm.max_children = 20        ; default is 5 on cheap plans
pm.start_servers = 4
pm.min_spare_threads = 2
pm.max_spare_threads = 8
; Avoid hitting 100% CPU
pm.max_requests = 500
TIP: Restart PHP‑FPM after changes: systemctl restart php8.2-fpm (or service php-fpm restart on CentOS).

4. Set Up Supervisor (if allowed)

If your host permits supervisord, create a config file in /etc/supervisor/conf.d/laravel-queue.conf:

[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /home/username/site/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
user=username
numprocs=2
redirect_stderr=true
stdout_logfile=/home/username/logs/queue_worker.log
stopwaitsecs=3600
WARNING: Some shared hosts kill long‑running processes after 30 minutes. If you see “Supervisor stopped” in the logs, move to a low‑cost VPS (e.g., $5/mo).

5. Run a Quick Queue Test

php artisan queue:retry all
php artisan tinker
>>> dispatch(function () { Log::info('Queue test success'); });
# Check log file:
tail -f storage/logs/laravel.log

6. Composer Autoload Refresh

composer dump-autoload -o
php artisan config:cache
php artisan route:cache

VPS or Shared Hosting Optimization Tips

SUCCESS: On a fresh Ubuntu 22.04 VPS with 1 vCPU, 1 GB RAM, the same queue runs 3× faster after the tweaks.
  • Swap Management: sudo swapon --show. If swap is zero, create a 512M swap file to avoid OOM kills.
  • Nginx FastCGI Buffers: fastcgi_buffers 8 16k; in php.conf.
  • MySQL Tuning: Set innodb_buffer_pool_size=256M for small VPS.
  • Redis Persistence: Use save 900 1 to snapshot every 15 minutes; avoid AOF on low‑end plans.
  • Cloudflare Cache‑Purge: Add a page rule to bypass caching for /api/* endpoints that push jobs.

Real World Production Example

Acme SaaS runs a Laravel API on a 2‑core VPS behind Nginx, using Redis for queues and MySQL 8 for persistence. After deploying the above changes, they measured:

MetricBeforeAfter
Avg. job latency7.3 s2.1 s
Failed jobs (24 h)423
CPU usage (peak)92 %68 %

Before vs After Results

# BEFORE (shared host)
[2026-05-04 12:45:12] production.ERROR: Connection refused (SQL: select * from jobs where queue = "default" and reserved_at is null limit 1)

# AFTER (VPS with tuned FPM & Supervisor)
[2026-05-04 12:45:13] production.INFO: Queue test success

Security Considerations

  • Never expose Redis without a password. Add requirepass YOUR_STRONG_PASSWORD in redis.conf.
  • Limit Supervisor’s user directive to the application user, not root.
  • Set APP_ENV=production and APP_DEBUG=false before going live.
  • Use ufw allow from 127.0.0.1 to any port 6379 to lock down Redis to localhost.

Bonus Performance Tips

  1. Enable opcache.fast_shutdown=1 in php.ini for faster script termination.
  2. Compress JSON API responses with gzip in Nginx: gzip on; gzip_types application/json;
  3. Batch queue jobs: use dispatchNow() for tiny tasks, reserve queue:work --daemon for heavy background work.
  4. Schedule php artisan schedule:run via cron every minute, not every 5 minutes, to keep the scheduler responsive.
  5. Leverage Laravel Horizon on VPS for real‑time queue monitoring.

FAQ

Q: My host blocks Supervisor entirely. What can I do?
A: Use Laravel’s built‑in queue:work as a cron entry that runs every minute. It’s less efficient but works on restrictive shared plans.
Q: Should I switch from Redis to the database driver?
A: For low‑traffic sites, the database driver avoids network issues. For scaling, stick with Redis and fix the firewall.

Final Thoughts

Queue workers hanging on shared hosting is rarely a Laravel bug; it’s an infrastructure mismatch. By confirming connectivity, tuning PHP‑FPM, configuring Supervisor (or a cron fallback), and tightening security, you can resurrect background jobs in under ten minutes. When you outgrow the shared plan, the same settings will translate directly to a cheap VPS—giving you the performance headroom to add new features without sacrificing reliability.

Monetize Your Fixes

Ready to host Laravel‑WordPress hybrids on a platform built for developers? Check out Hostinger’s cheap, secure VPS. Their one‑click Laravel installer, dedicated Redis, and unlimited databases let you apply every tip from this guide without fighting shared‑host limitations.

No comments:

Post a Comment