kreitje/nova-horizon-stats
A Laravel Nova card that surfaces Laravel Horizon queue metrics—throughput, wait times, and job stats—right on your Nova dashboard, so you can monitor queue health without leaving the admin panel.
This package adds custom cards to the Laravel Horizon dashboard; v0.3 introduces a Workload card that surfaces the current per-queue workload, with optional queue filtering so you can focus on only the queues you care about.
Install and publish
composer require <vendor>/<package>
php artisan vendor:publish --tag=<package>-config # publish the queue filter config
Publish views too if you plan to restyle the card (--tag=<package>-views).
Register the card with Horizon. Custom Horizon cards are registered from a service provider (typically App\Providers\HorizonServiceProvider or a dedicated provider) by appending the package's card class to Horizon::cards([...]). Check the package README for the exact class name — it will be a Laravel\Horizon\Card subclass.
Look here first: the published config file (queue allow-list) and the Horizon dashboard at /horizon. The Workload card renders alongside the built-in metrics cards.
First use case: open /horizon, confirm the Workload card shows per-queue pending/waiting counts. Then set queues => ['default', 'critical'] in the config to narrow it to your production queues.
Note: this is a
0.xrelease. The Workload card is additive, but under semver a minor bump can still carry breaking changes — pin the version incomposer.jsonand read release notes before upgrading.
Queue filtering per environment. Put the allow-list in config and drive it from env so staging can show all queues while production shows only the ones on-call cares about:
// config/<package>.php
'queues' => env('HORIZON_WORKLOAD_QUEUES')
? explode(',', env('HORIZON_WORKLOAD_QUEUES'))
: ['default', 'critical', 'notifications'],
This keeps the card meaningful — an unfiltered workload view across dozens of queues is noise.
Multiple card instances. Because the queue list is config-driven, you can register the card more than once if the card class accepts queues via constructor/setter — e.g. one card for customer-facing queues and one for internal batch queues. Prefer this over a single wide card.
Conditional registration. Only register the card outside production, or only for supervisors who need it, by wrapping Horizon::cards() in an environment/role check in the service provider. Horizon's own viewHorizon gate already controls dashboard access, but conditional registration keeps the dashboard lean for everyone else.
Pair with built-in metrics. Workload (instantaneous backlog) complements Horizon's Jobs Past Hour and Max Wait Time cards well: workload tells you where the pressure is, wait-time tells you how bad it is. Use them together when triaging a backlog before reaching for horizon:list or the failed-jobs view.
Dashboard-as-documentation. Commit the queue filter config so the set of "watched" queues is reviewed like code — adding a new queue to the app should trigger a review of this list.
php artisan config:clear (or config:cache in deploy) — the card reads from config on each dashboard poll, so a stale cache silently shows the wrong queues.default on two connections is two workloads; if the card filters by bare queue name you may see merged or missing entries. Verify with php artisan horizon:list.laravel/horizon and re-check the card after each Horizon bump. Watch for a blank card or a JS console error when this happens.Horizon::cards()? (2) did you clear config/view caches? (3) are views published and up to date after upgrading to 0.3? (4) check storage/logs/laravel.log — a failing card often throws during the dashboard data request rather than at boot.How can I help you explore Laravel packages today?