DeployManage, server management for any cloud
Launch a server with Redis and Supervisor already installed, run php artisan horizon as a managed daemon, and add horizon:terminate to the deploy script so every release restarts your workers on the new code. Your server, your Redis, no per-worker billing.
One-time demo, no credit card required.
Horizon requirements read from the Laravel 12 Horizon docs; Forge, Laravel Cloud and DigitalOcean figures from their own docs and pricing pages, October 2026.
| Server | Provider | Load |
|---|---|---|
|
web-01.prod
fsn1
|
Hetzner |
32%
|
|
web-02.prod
fsn1
|
Hetzner |
47%
|
|
db-01.prod
fra1
|
DigitalOcean |
18%
|
|
worker-01
eu-central-1
|
AWS |
61%
|
|
mail-01
gra
|
OVHcloud |
9%
|
Laravel Horizon needs three things from a host: Redis (Horizon does not work with Redis Cluster or other queue drivers), a process monitor such as Supervisor that keeps php artisan horizon alive, and a deploy step that runs php artisan horizon:terminate so the master process restarts on new code. Shared hosting rarely gives you the first two. Laravel Cloud's managed queues do not support Horizon at all, so Horizon there means a self-managed worker process. The simplest production setup is a VPS with Redis and Supervisor, about $24 a month for a 4 GB DigitalOcean server plus a panel fee: $12 on Laravel Forge Hobby, $59 on DeployManage Starter.
Horizon rarely fails because of Horizon. It fails because the process was started by hand in an SSH session and died when the session closed, because a deploy shipped new job classes while the old master process kept running yesterday's code, or because Redis filled up its memory and started evicting the very keys Horizon uses to track jobs.
Each of those is a hosting problem, and each one is solved once: Supervisor owns the process, the deploy script tells Horizon to finish its jobs and exit, and Redis runs on a server with enough memory and a sane eviction policy. After that, queues stop being the thing your team checks first when something goes wrong.
Pick DigitalOcean, Hetzner, AWS, Vultr, Linode or your own Ubuntu VPS. Provisioning installs Nginx, PHP-FPM with the redis extension, Composer, redis-server, Supervisor and MySQL, MariaDB or Postgres, then closes every port except 22, 80 and 443. Redis listens on localhost only.
Add a daemon with the command php /home/deploy/your-site/current/artisan horizon. DeployManage writes the Supervisor program, sets autostart and autorestart, and logs its output, so Horizon comes back on its own after a crash or a reboot.
The deploy script is yours to edit per site. Add php artisan horizon:terminate after migrations and Horizon finishes the jobs in flight, exits, and Supervisor starts it again on the new release. No job is killed halfway through.
One cron entry runs schedule:run every minute. Schedule horizon:snapshot every five minutes in routes/console.php and the Horizon metrics graphs fill in without extra setup.
On Growth and Business each push builds a fresh release directory with shared .env and storage, then flips the current symlink in one step. If a release breaks a job, roll back and Horizon restarts on the previous code.
Growth includes 10 team members and Business is unlimited. Every deploy, rollback and daemon change is logged with who made it, so a stuck queue can be traced back to the release that caused it.
Paste an API token from DigitalOcean, Hetzner, Vultr, Linode or AWS, or add any Ubuntu server over SSH. The server stays in your account and on your provider's invoice.
A 4 GB server in a US region runs the web app, Redis and a Horizon pool of up to 10 processes for most SaaS apps. Add the domain, pick PHP 8.3, and the certificate is issued and renewed for you.
Set QUEUE_CONNECTION=redis in the production .env, add the horizon daemon, and add horizon:terminate to the deploy script. Restrict the /horizon dashboard in HorizonServiceProvider before the first deploy.
Every push runs composer, migrations and caches in a new release, then tells Horizon to finish its jobs and restart. The deploy log shows each step and who triggered it.
Software and platform prices from each vendor's own pricing page or docs, read in October 2026, in USD per month. Server cost is separate on the two panels. The honest headline: Laravel Forge is the cheapest way to run Horizon on one VPS. DeployManage costs more and fits teams and agencies running Horizon across several servers or clouds that need seats, atomic releases and a deploy log.
swipe to see all columns →
| What you are comparing | DeployManage | Laravel Forge | Laravel Cloud | Shared hosting |
|---|---|---|---|---|
| Monthly software fee | Starter $59, Growth $129, Business $299; half price billed yearly | Hobby $12, Growth $19, Business $39 | Starter $5, Growth $20, Business $200, plus metered usage | Usually $3 to $15 |
| How Horizon runs | Supervisor daemon you add in the panel | Horizon integration creates the daemon | Not on managed queues; a self-managed worker process instead | Usually not possible; cron workarounds only |
| Restart on deploy | horizon:terminate in your deploy script | Added to the deploy script by the integration | You configure it in the worker setup | Manual |
| Redis | redis-server installed on the server | Installed on the server | Valkey cache, $6 a month for 250 MB Flex in US East | Rarely offered |
| Zero downtime deploys | Growth and Business, atomic with rollback | Yes, on one server per site | Handled by the platform | No |
| Root access | Yes | Yes | No | No |
| One app with Horizon, all in | $83 ($24 server + $59 Starter) | $36 ($24 server + $12 Hobby) | About $57 (web, worker, MySQL, Valkey on Growth) | Not a fit |
Notifications, invoices, outgoing webhooks and imports all go through the queue. Horizon's auto balancing moves workers to whichever queue is backed up, and the dashboard shows the team where jobs are waiting.
Each client app has its own Redis database, its own Horizon daemon and its own deploy script. Contractors get seats, and the deploy log answers the question of who restarted what, and when.
The queue ran on a cron job with --stop-when-empty and big jobs kept timing out. The move is to a 2 or 4 GB VPS where Horizon runs all the time under Supervisor, which is what the app needed from the start.
Every worker is a separately billed service on most platforms. On your own server, ten Horizon processes cost the same as one, because you pay for the machine, not for each process.
To run Laravel Horizon in production, set your queue connection to Redis, keep php artisan horizon running under a process monitor such as Supervisor, and run php artisan horizon:terminate during every deployment so the process restarts on the new code. Then restrict the /horizon dashboard with the viewHorizon gate, because Horizon only allows access in the local environment until you do.
Laravel's own Supervisor example uses autostart and autorestart, and it sets stopwaitsecs to 3600 so a long job is not killed when Supervisor stops the process. Two more settings save real pain later. Keep the Horizon timeout for each supervisor a few seconds shorter than retry_after in config/queue.php, or jobs can run twice. And schedule horizon:snapshot every five minutes, or the metrics screen stays empty.
In DeployManage, the daemon screen writes the Supervisor program for you, the deploy script carries horizon:terminate, and the scheduler cron is created with the site. Today the daemon form sets a 10 second stop wait, which only matters when the daemon itself is stopped; on a normal deploy horizon:terminate lets every running job finish first.
Not reliably. Horizon is a long running process that needs Redis and a process monitor, and most shared hosting plans offer neither. A command started over SSH stops when the session closes, and hosts usually kill long running processes anyway.
There are workarounds, such as a cron job that checks every few minutes whether Horizon is still running and starts it if not. They are fine for a side project. For an app where a queued password reset or a paid invoice email has to go out in seconds, a small VPS with Supervisor is the cheaper option once you count the hours spent chasing stuck jobs.
Not on its managed queues. Laravel Cloud's queue documentation states that Horizon does not support managed queues, so running Horizon on Laravel Cloud means a self-managed worker process with a Redis compatible queue that you configure yourself. Managed queues use their own dashboard for failed jobs and retries instead.
That setup works, but it gives up the main thing Laravel Cloud sells for queues, which is workers that scale to zero and are billed per second. A worker process running Horizon all month bills like an always on instance, about $12 a month for Flex 1 GB in US East, on top of the plan fee, the web compute, the database and a Valkey cache. Our Laravel Cloud pricing page walks through the rest of that bill.
Yes. Laravel Forge has a Horizon integration that creates the Horizon daemon and adds horizon:terminate to your deployment script, and its zero downtime deployments restart queues as part of the release. For one app on one server, Forge Hobby at $12 a month is the cheapest managed way to run Horizon we know of.
Where teams outgrow it is the same place they outgrow Forge in general: several servers across more than one cloud, contractors who need their own seats, and a deploy history someone outside engineering can read. That is the gap our Laravel Forge alternative page compares in detail.
On your own server, Horizon itself costs nothing extra: a 4 GB DigitalOcean server at $24 a month runs the web app, Redis and a pool of up to 10 Horizon processes for a typical SaaS, plus whatever your panel costs. That is $36 a month with Forge Hobby or $83 with DeployManage Starter.
| Setup | Server | Panel or platform | Total per month |
|---|---|---|---|
| One app, Horizon, Redis, MySQL on one 4 GB server, Forge Hobby | $24 | $12 | $36 |
| Same, DeployManage Starter | $24 | $59 | $83 |
| Laravel Cloud Growth with Flex 1 GB web, a Flex 1 GB worker for Horizon, MySQL Flex 1 GB, Valkey 250 MB, $5 credit applied | None | $20 plan plus about $37 usage after the credit | About $57 |
| Five client apps on two 4 GB servers, DeployManage Growth | $48 | $129 | $177 |
Laravel Cloud figures use the US East monthly caps on its pricing page (Flex 1 GB $12, MySQL Flex 1 GB $11, Valkey Flex 250 MB $6) plus a little storage. The point of the table is not that one option always wins. It is that on a server you own, adding Horizon processes costs memory, not money, while on a platform every always on worker is a line on the invoice.
For most apps, a 2 GB server is enough for the web app plus Redis plus a Horizon pool of three to five processes, and a 4 GB server is the safer choice once you run 10 or more processes or keep large payloads in Redis. Each PHP worker usually sits between 40 and 120 MB depending on what your jobs load.
Watch two numbers after launch. The first is Redis memory: set a maxmemory limit and use the noeviction policy for a queue database, because evicting queue keys loses jobs silently. The second is maxProcesses in config/horizon.php, which should fit in the RAM left after PHP-FPM and the database. When the queue regularly backs up, move Horizon to its own server and point it at the same Redis; DeployManage manages both servers from one panel. If you run Filament imports or exports on the same queue, our Filament hosting page covers the batch tables those jobs need.
Ready to stop managing servers by hand? DeployManage provisions, deploys and monitors your fleet from one dashboard.
Get startedA VPS with Redis and Supervisor, managed by a panel that runs Horizon as a daemon and adds horizon:terminate to every deploy. Laravel Forge is the cheapest for one server. DeployManage fits teams running Horizon across several servers or clouds that need seats and a deploy log.
Yes. Horizon only works with Redis queues, and it is not compatible with Redis Cluster. Set QUEUE_CONNECTION=redis and do not reuse the connection name horizon for anything else, because Horizon reserves it internally.
Run php artisan horizon:terminate as a step in the deploy script. Horizon finishes the jobs it is processing, exits, and Supervisor starts it again on the new release. In DeployManage you add the line once to the site's deploy script.
Not on Laravel Cloud's managed queues, which Laravel's docs say Horizon does not support. You can run it as a self-managed worker process against a Redis compatible cache, billed like any always on instance.
You need some process monitor that restarts php artisan horizon if it exits. Supervisor is what Laravel's docs use and what DeployManage configures. systemd also works, but you then manage the unit file yourself.
Usually 10 to 20 alongside the web app, Redis and a small database, because a PHP worker typically uses 40 to 120 MB. Measure your own jobs with the Horizon metrics screen and set maxProcesses to fit the free memory.
Horizon is an open source Laravel package, so there is no licence fee. What you pay for is the server, Redis and whatever panel or platform keeps it running. On DeployManage every account starts with a one-time demo, then Starter is $59 a month.
Edit the viewHorizon gate in app/Providers/HorizonServiceProvider.php so only specific users can open /horizon. Outside the local environment Horizon denies access until you do, so set the gate before the first production deploy.
Connect a cloud account, launch a server with Redis and Supervisor, and push your first release with Horizon restarting on every deploy. Every account starts with a one-time demo, no card required.