genealabs/nova-horizon
A Laravel Nova integration for Horizon that brings queue and worker monitoring into your Nova dashboard, letting you view supervisors, jobs, and workload metrics without leaving the admin panel.
Architecture fit. This package is not a standalone capability; it is a thin adapter between two systems the product must already own. The architecture fit is therefore a binary gate, not a spectrum: it fits only if (a) Laravel Nova is the admin surface, (b) Laravel Horizon is running on Redis and actively processing jobs, and (c) the team is on Nova 4. If any one of those is false, the package contributes zero and the correct decision is to use /horizon directly or build a small Nova view onto Laravel Pulse. For a TPM, the key framing is that this is audience expansion, not new observability — Horizon already has the data; this package moves it in front of people who don't have Horizon credentials.
Integration feasibility. Low effort, high verification burden. Registration is a single entry in NovaServiceProvider::tools() — notably not dashboards() — plus a canSee closure. The real work is not installation but due diligence: read vendor/genealabs/nova-horizon/src end-to-end (small enough for ten minutes) and determine one thing above all — whether the tool consults Horizon's viewHorizon gate. If it renders an iframe or re-hosts Horizon assets without checking that gate, Nova users could see failed-job payloads and exception traces they'd be blocked from at /horizon. That is a data-exposure finding, not a cosmetic issue, and it should be an explicit go/no-go criterion in the plan.
Technical risk. Concentrated in four places:
canSee and Horizon's viewHorizon are independent systems. This is manageable (make Nova visibility a strict subset of Horizon's gate, test with a non-admin account) but only if someone actually does it.Key questions to resolve before committing:
viewHorizon, and does it render via iframe or re-hosted assets? (Determines both security posture and upgrade fragility.)horizon:snapshot scheduled? Without it, throughput and wait-time cards show zeros — the single most common false "it's broken" alarm.Stack fit. Requires Laravel with Nova 4 (installed and reachable at /nova), Horizon configured and php artisan horizon:status returning running, QUEUE_CONNECTION=redis, and a scheduled horizon:snapshot. Verify all four before touching composer — this package does nothing on its own, and an hour can be lost debugging an empty page that was never going to work.
Migration path. This is additive, not a migration. There is no schema change, no data movement, and no runtime coupling to application code. Rollback is deleting one line from tools(). That reversibility is the package's strongest argument and should be stated explicitly in the business case — it lowers the cost of being wrong to near zero.
Compatibility. Three-way pinning: Nova major/minor, Horizon minor, this package (^0.6.1). Record the known-good triad in the dependency inventory so the next developer does not assume Nova 5 coverage. Re-validate on every Nova major upgrade and every Horizon minor that touches front-end assets. Never resolve with --ignore-platform-reqs.
Sequencing. A four-step rollout that keeps risk bounded:
/horizon reachable and frameable from the Nova host (watch for X-Frame-Options/frame-ancestors violations behind proxies or strict CSP).config('app.horizon_tool_enabled') ? [NovaHorizon::make()->canSee(...)] : []. Roll out to a pilot group of engineers first, then support supervisors. Keep /horizon bookmarked as the deep-dive fallback so team behavior doesn't change if the tool breaks.php artisan queue:monitor default:100. If they agree, wiring is correct and it can be handed to a non-engineer. Only then widen the audience.Audience tiering. Decide up front whether engineers get full worker/supervisor/payload detail while support gets queue depth, oldest job age, and failed count. If the package can't express that split, gate the whole tool to support supervisors and have them relay — a narrower surface beats an uncontrolled one.
Maintenance. Low but non-zero, and it must have a named owner. Ongoing obligations: keep the Nova/Horizon/package triad pinned and re-validated on major upgrades; keep horizon:snapshot scheduled; maintain a fork branch; expect to write the Nova 5 patch in-house if that upgrade happens. This is the single largest hidden cost and should be sized in the plan (roughly half a day of adoption plus periodic upgrade re-validation), not waved through as "just a composer require."
Support. No vendor support path exists. Escalation is internal: the fork owner. That is acceptable for vendored glue but must be documented and accepted by whoever signs off. The upside is that narrow reactive patches do land upstream — 0.6.1 is exactly that — so the fork and upstream can stay loosely coupled.
Scaling. Each viewer adds Horizon Redis polling plus a Nova asset bootstrap. A handful of operators is effectively free; opening it to an entire CS organization is not. If the audience grows, the mitigation is a read-only cached snapshot rather than live polling. Set an explicit audience ceiling at rollout and revisit before widening.
Failure modes and their signatures:
/horizon load; does Gate::allows('viewHorizon') return true for this user; is the tool registered in tools() not dashboards(); is the provider auto-discovered. Usually canSee or stale Nova cache — php artisan nova:publish and a hard refresh.horizon:snapshot schedule. Most common false alarm; document it in the runbook.frame-ancestors violation. Devtools, then either relax the policy for that path or accept engineer-only access on a separate URL.Ramp-up. Short for engineers, minutes for support. The ramp-up artifact that matters is not documentation of the tool — it's the release-gate checklist: after any deploy touching queue code, open the Nova tool, confirm queue depth returns to baseline within the normal window, confirm no new failures in the last 15 minutes. Its value is that someone who did not write the code can run it. Success should be measured on that axis — support tickets deflected and time-to-triage shortened — with an explicit caveat that this dashboard must be paired with Sentry/Bugsnag/Oh Dear/APM for alerting, SLOs, and history. Horizon metrics are a rolling window (~24h) and trimmed; this answers "is it stuck right now," never "how did the queue perform last Tuesday."
How can I help you explore Laravel packages today?