fof/horizon
Brings Laravel Horizon's queue monitoring dashboard into Flarum's admin area, letting administrators inspect Redis-backed queues, recent jobs, throughput, and worker status. Requires Redis and proper Horizon setup, making it best suited to advanced or high-traffic forums.
Framing correction up front: fof/horizon is not a general-purpose Laravel package — it is a Flarum extension (FriendsOfFlarum) whose job is to wire Laravel Horizon into Flarum's queue subsystem. Flarum 1.x sits on a subset of Illuminate components but is not a Laravel application: it has its own service provider lifecycle, container bootstrapping, and queue wiring. Treat this package as glue code between two systems we'd otherwise have to glue ourselves, not as a library. That distinction drives every risk below.
Architecture fit. Horizon itself is Laravel-official, mature, and well-documented — the underlying capability (queue throughput, wait-time, runtime, retry/failure introspection, supervisor autoscaling) is genuinely valuable and is exactly the class of tooling Flarum's stock queue story lacks. The adapter is thin by necessity: register Horizon's service provider, publish/merge an horizon.php config, gate the dashboard routes behind Flarum admin authorization, and expose the Horizon commands through Flarum's console. Architecturally this is the right shape. The question is whether the adapter is correct against Flarum's queue contracts and stays correct across Flarum majors.
Integration feasibility. Moderate. Path is composer require fof/horizon, enable the extension, ensure the queue driver is redis, publish config, run horizon:install/horizon, and supervise a long-running process. The hard prerequisite is non-negotiable: Horizon only works on Redis. If we run sync (Flarum's common default) or database, this package delivers nothing. Composer feasibility is the real gate — Horizon pins Illuminate/Symfony ranges, and Flarum core pins its own; a version conflict is plausible and would surface at composer update, not at runtime.
Technical risk.
Key questions.
Horizon::auth() bound to Flarum's authorization?horizon daemon, or does it wrap Flarum's cron-driven queue:work?Stack fit. Flarum 1.x, PHP 8.x, Redis as the queue backend, Supervisor or systemd managing a php flarum horizon process. This is a queue architecture change, not an extension install — it moves us from a cron-invoked worker to a resident, self-managing process pool. Environments on sync or database drivers are out of scope; do not attempt to force-fit.
Migration path. Run Horizon alongside the existing queue:work cron for a bounded window rather than cutting over in one step. Concretely: stand up Redis-backed queues on staging, enable the extension, verify the dashboard against known-good job traffic, then disable the cron worker on production and let Horizon own the queues. Keep the old cron entry commented, not deleted, for one release cycle. Config ownership should live in our repo (config/horizon.php or the extension's publish target), not in a vendor directory that a composer update will silently overwrite.
Compatibility. Build an explicit pin matrix before merging: Flarum core version ↔ laravel/horizon major ↔ PHP minor ↔ Redis server version. Constrain fof/horizon and laravel/horizon to exact or tilde ranges in composer.json and treat any bump as a change requiring a staging pass. Because the adapter is low-traffic, assume we are the compatibility testers; the CI signal from upstream will be thin or absent.
Sequencing.
horizon.php environments (production, staging) with memory and timeout limits.horizon:terminate on every deploy so workers pick up new code — this is the single most common operational miss and causes silent stale-code execution.Maintenance. FriendsOfFlarum is a volunteer community org; this specific extension has essentially no downstream users. Budget for the possibility that we become the de facto maintainer — either by forking and vendoring, or by accepting a frozen pin. A one-maintainer, one-star adapter is a sustained-but-low maintenance cost: small surface area, but no one else is watching it. Recommend a documented fork strategy in the ADR.
Support. GitHub issues and the Flarum community forum only. No SLA, no vendor. Mitigation: Horizon's own documentation is genuinely good, so most production issues (stuck supervisors, memory, Redis connectivity) are debuggable from Laravel docs plus horizon:status/horizon:list. The Flarum-specific surface is small enough that a Laravel-fluent engineer can read the extension source in an afternoon.
Scaling. This is where the package earns its keep. Horizon gives per-queue process pools, autoscaling supervisor strategies (simple/auto), and queue balancing (auto/false) — meaningful gains over hand-tuned queue:work invocations. The trade: Redis becomes a hard single point of failure for all async work, and capacity planning shifts from "how many cron workers" to "how much Redis memory and how many processes." Plan Redis HA and memory headroom accordingly; Horizon's metrics are only useful if Redis survives.
Failure modes.
horizon:terminate. Highest-probability incident; fix in the deploy pipeline.memory limit and auto-restart, but only if configured; defaults are often too generous.composer update during an unrelated Flarum upgrade, blocking the whole upgrade. Pin tightly.Ramp-up. For an engineer already fluent in Laravel queues: roughly 3–5 days to a confident staging deployment, plus 1–2 days for the Flarum-specific adapter and auth-gate review. For a team without Laravel queue experience, add a week: the conceptual load is Redis queue semantics, supervisor/process management, and Horizon's config vocabulary — none of which Flarum's own docs cover. The Flarum side is the smaller half of the learning curve; the operational half (supervision, deploy hooks, Redis capacity) is where teams actually stumble.
PM recommendation. The capability is worth adopting; this package is not a safe default. Proceed to a timeboxed staging spike, but evaluate stock laravel/horizon with a thin in-house provider as the fallback — the adapter's job is small enough that owning it may be cheaper than depending on an unmaintained one.
How can I help you explore Laravel packages today?