lkaemmerling/laravel-horizon-prometheus-exporter
Expose Laravel Horizon queue metrics to Prometheus for monitoring and alerting. Track jobs, queues, wait times, throughput, and worker health via a scrapeable endpoint, making it easy to visualize Horizon performance in Grafana and catch backlog or failure issues early.
Architecture fit. lkaemmerling/laravel-horizon-prometheus-exporter is a thin, single-purpose Laravel package: a service provider plus a config file that exposes Horizon's queue metrics on an HTTP endpoint in Prometheus text format. It slots into an existing Laravel + Horizon + Prometheus/Grafana topology without touching application code, queue definitions, or the database. It is not a general queue-observability tool — its blast radius is deliberately small, which is its main architectural virtue and its main limitation. Relevant only to Redis-backed queues managed by Horizon; teams on database, sqs, or other drivers get no value from it.
Integration feasibility. High. Composer install, optional vendor:publish of the config, a scrape job in Prometheus, and a Grafana dashboard. No migrations, no schema, no runtime hooks into job dispatch. Realistic effort for an engineer familiar with the stack: half a day to a day including dashboard and alert wiring. The main integration decision is the metric storage backend used by the underlying Prometheus PHP client — the in-memory adapter does not survive across PHP-FPM workers, so a shared backend (Redis/APCu) is typically required, and that backend choice is the only non-trivial design call.
Technical risk. Moderate, concentrated in three areas:
laravel-shift). This is a mechanical dependency-constraint change, not feature work — which is good news (the package is not dead) and a caution (mechanical compatibility PRs are not evidence of production testing against Laravel 13). The inverse risk matters more: before this release, the package's illuminate/* constraint could block a framework upgrade entirely. A monitoring package should never gate a platform upgrade, and historically this one could.Key questions.
laravel/horizon version bounds in v1.8.3's composer.json?Stack fit. Requires: Laravel (constraint per v1.8.3 — verify before pinning), Horizon on Redis, PHP version per package constraints, and a Prometheus-compatible scraper. Fits cleanly into an existing observability stack; adds nothing to the request path or job lifecycle. Poor fit for teams without Prometheus, or without Horizon.
Migration path. Additive, no migration. There is no prior assessment and no incumbent tool to displace — the realistic comparison is "Horizon's built-in dashboard, read by a human" versus "metrics scraped and alerted on." The former stays; this package complements it rather than replacing it.
Compatibility. Two axes to verify before commitment: (a) our Laravel/PHP versions against the package's constraints in v1.8.3, and (b) our Horizon major version against what the package reads. Treat (b) as the higher-risk axis — Laravel compatibility is declared, Horizon compatibility is implicit.
Sequencing. Order matters here:
Maintenance. Very low steady-state: no schema, no background jobs, no data retention of its own. The recurring cost is version-tracking — someone must watch this repo before each Laravel and Horizon upgrade, because it sits in the upgrade critical path. Assign explicit ownership; an unowned monitoring dependency is how you discover the constraint conflict during a release window.
Support. Community, effectively single-maintainer, no SLA and no commercial backing. Mitigations: pin exact versions, vendor/fork the package if it ever lags a framework upgrade we need, and keep the config surface small enough that a fork stays cheap. The v1.8.3 release is a positive maintenance signal — but a single automated compat PR is a data point, not a trend.
Scaling. Cost scales with queues × metrics × scraped instances, not with job throughput, so it stays cheap. Two things to watch: (a) if the shared metric backend is Redis, scrapes add read load to the same Redis instance backing the queues — size and monitor accordingly, or isolate; (b) in multi-node/multi-pod deployments, naively scraping every instance duplicates series and inflates cardinality. Decide deliberately whether you scrape per-instance (label by instance, useful for worker-health diagnosis) or once per cluster.
Failure modes.
Ramp-up. Low — roughly a day for a mid-level engineer to ship endpoint, dashboard, and a first alert set. The real ramp-up is organizational: agreeing on metric naming/labels, baseline thresholds, and who owns the dashboard. Budget more for that conversation than for the integration itself.
How can I help you explore Laravel packages today?