Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jonlink's avatar

Is Horizon worth the trouble if you are building an API?

Playing around with queues and Horizon definitely seems appealing except that we are using Laravel strictly as a backend API. Horizon seems to expose a lot through blades.

Does anyone have experience with this? Is it easier to create our own Horizon lite on top of the queue or to hack Horizon to work in an API setting?

0 likes
9 replies
lbecket's avatar

I would argue that the benefit of the features "exposed through blades" outweighs the risk of that exposure. If you want this functionality, then I would just embrace it and not try to hack a "Horizon lite."

jonlink's avatar

Just to clarify, we wouldn't hacking a horizon lite, we'd be making our own proper package that wouldn't push a front end solution on a backend tool. Supervisor is easy enough, the scaling logic wouldn't be that bad either. What I like (and don't really want to build) are the bits to make it so that all the jobs (including failed) are stored in Redis. I wish Laravel just did that out of the box, but oh well. But this is definitely going to be a bit of re-inventing the wheel, which is not a great use of resources.

The hacks would happen if we use Horizon because we'd need to make it work from an API. The interactive frontend bits of Horizon aren't exposed as an API, they're all web routes which will be inaccessible to an API as the servers are all tucked behind an API gateway. We might be able to get away with just throwing our own 'api' routes file on top of Horizon. I don't know if anyone has experience with that and could speak to whether it was effective or just made things more annoying (esp when Horizon gets updated)

EDIT: I guess what I wish is that there was Horizon, "a beautiful dashboard for your Laravel powered Redis queues" and then also Zenith, "a beautiful code-driven configuration for your Laravel powered Redis queues" :D

Snapey's avatar

@jonlink If what is offered free of charge does not suit your requirements, write your own.

jonlink's avatar

Thanks. From the tone here, it sounds like you're possibly implying I'm being unreasonable or ungrateful. Just to be clear, that isn't the case. It's a great solution and I deeply appreciate it. I'm trying to figure out if it'd be sensible to bend what's on offer to our needs.

Snapey's avatar

@jonlink absolutely. things like " we'd be making our own proper package"

I say carry on.

1 like
martinbean's avatar

@jonlink Horizon is its own standalone package, with its own routes and views. Just install it, and then access it via its /horizon URI. It doesn’t care what you’re building your front-end/client with.

jonlink's avatar

@martinbean Thanks for your reply. I realize it's standalone, the problem in this case is that it won't be accessible. To get Horizon's front end to work, we'd have to turn off the enforced json returns, tweak all the listen routes, and make a few other more trivial changes.

I realize to some degree we've painted ourselves into a corner here by enforcing our service returns json, but I think this is a sensible restriction considering the purpose. This is in no way Horizon's fault.

jonlink's avatar

Thanks everyone, from what I'm seeing here it looks like we'd be best off doing a small custom package to manage/scale the queue. Appreciate everyone's feedback!

martinbean's avatar

@jonlink You really seem to be taking the most awkward path to solving the problem.

If you have middleware or something enforcing JSON responses, then just disable that for Horizon’s URI (similar to how Laravel’s CSRF middleware lets you disable checks for specific URIs). Or, put your API routes in your routes/api.php file and your middleware that enforces JSON responses in your api middleware group.

You’re really making this problem bigger than it should be.

1 like

Please or to participate in this conversation.