Why your Laravel queue workers need to restart more often than you think
· 5 min read
php artisan queue:work is meant to run forever, and that's exactly the problem. A worker that started before your last deploy is still running the old code — including old config, old service bindings, and any memory leaks that build up over a long process lifetime.
Deploys don't restart workers for you
Unless your deploy pipeline explicitly runs queue:restart, workers keep processing jobs against whatever code was loaded when they booted. This is the single most common cause of "it works locally but the production queue is doing something weird" bug reports.
Memory leaks are cumulative, not sudden
PHP's garbage collection handles most things, but long-lived Eloquent models, event listeners that never get torn down, and third-party SDKs that cache aggressively all add up. A worker that's fine at hour one can be swapping by hour twelve. --max-jobs and --max-time flags aren't optional flourishes — they're how you bound the blast radius of a leak you haven't found yet.
Supervisor config that actually reflects this
[program:laravel-worker]
command=php artisan queue:work --sleep=3 --tries=3 --max-jobs=1000 --max-time=3600
autorestart=true
stopwaitsecs=3600
The combination of --max-jobs and --max-time means a worker retires itself well before it becomes a problem, and Supervisor brings a fresh one up immediately. Combined with queue:restart on deploy, this closes both gaps — stale code and creeping memory — with configuration instead of vigilance.