huangdijia/laravel-horizon-restart
A lightweight Laravel package for restarting Horizon workers programmatically or from an Artisan command. Useful after deployments or config changes, it sends Horizon's restart signal so workers reload gracefully without manual intervention.
composer require huangdijia/laravel-horizon-restart. The service provider is auto-discovered; there is nothing to register in config/app.php on any supported Laravel version.php artisan list | grep horizon. You should see the package's restart command alongside Horizon's stock horizon:terminate, horizon:pause, and horizon:continue.php artisan horizon:terminate in your deploy script with the package's restart command. The stock terminate kills workers immediately, dropping any job that is mid-flight; the package's restart drains in-flight work first, which is what you actually want on a deploy that ships changed job/handler code.vendor/huangdijia/laravel-horizon-restart/src/ — read the single command class end to end (it is small) to see exactly which Horizon lifecycle calls it makes and in what order. Then check php artisan horizon:status to confirm Horizon is actually running before you test the restart, otherwise the command will appear to hang or no-op.artisan migrate --force and after the new code is symlinked in and php artisan config:cache has run:
php artisan migrate --force
php artisan config:cache
php artisan horizon:restart
queue:restart only for non-Horizon connections. Horizon-managed Redis queues are covered by the restart command; SQS/database queues handled by plain queue:work supervisors are not, so keep a php artisan queue:restart for those.Artisan::call('horizon:restart') works from a deploy webhook controller, a php artisan app:deploy wrapper command, or a scheduled job. Wrap it in a queued job with ->onOneServer() if you trigger deploys from multiple app servers..env, Redis credentials, and the same APP_ENV as the running Horizon.deploy.php use task('horizon:restart', ...)->run('{{release_path}}/artisan horizon:restart') and hang it off deploy:symlink. In Envoyer, add it as an Activate New Release hook.php artisan horizon:status | grep -q running && php artisan horizon:restart || true so a first deploy doesn't fail the pipeline.APP_ENV, REDIS_*, or the horizon.php connection differ between where you run the command and where Horizon runs, it will pause nothing and wait forever (or return instantly having done nothing). Always run it on a host with the production .env.php artisan horizon:continue in a finally/|| cleanup step, and alert on queue depth so this surfaces fast.->timeout() on your CI step and decide explicitly whether a timeout should fail the deploy or hard-terminate (horizon:terminate) and accept job loss.config/horizon.php under environments. Check that block before debugging the package.php artisan config:cache before the restart so respawned workers pick up the new config — and remember Horizon reads config/horizon.php at boot, so a config change without a restart is inert.-vvv, tail storage/logs/laravel.log, and cross-check php artisan horizon:status / the Horizon dashboard's "paused" indicator before and after. If jobs stop processing after a deploy, checking the paused state is the first thing to do.illuminate/* and php constraints. If you're on Laravel 12 or PHP 8.4 with v3.0.0 pinned, Composer will refuse to resolve — bump to ^3.1. Conversely, on Laravel 10/11 there is no functional reason to rush the upgrade.How can I help you explore Laravel packages today?