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_CONNECTIONenv variable (e.g., set torediswhile 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
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
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
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
- 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;inphp.conf. - MySQL Tuning: Set
innodb_buffer_pool_size=256Mfor small VPS. - Redis Persistence: Use
save 900 1to snapshot every 15 minutes; avoidAOFon 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:
| Metric | Before | After |
|---|---|---|
| Avg. job latency | 7.3 s | 2.1 s |
| Failed jobs (24 h) | 42 | 3 |
| 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_PASSWORDinredis.conf. - Limit Supervisor’s
userdirective to the application user, not root. - Set
APP_ENV=productionandAPP_DEBUG=falsebefore going live. - Use
ufw allow from 127.0.0.1 to any port 6379to lock down Redis to localhost.
Bonus Performance Tips
- Enable
opcache.fast_shutdown=1inphp.inifor faster script termination. - Compress JSON API responses with
gzipin Nginx:gzip on; gzip_types application/json; - Batch queue jobs: use
dispatchNow()for tiny tasks, reservequeue:work --daemonfor heavy background work. - Schedule
php artisan schedule:runvia cron every minute, not every 5 minutes, to keep the scheduler responsive. - 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‑inqueue:workas 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, thedatabasedriver 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