Configuring Laravel Horizon on Laravel Forge: A Seamless Queue Strategy
Overview
Efficient queue management defines modern PHP applications. Laravel Horizon provides a beautiful dashboard and code-driven configuration for your Redis queues, while Laravel Forge simplifies the server management. Integrating them isn't just about turning on a switch; it's about ensuring your queue workers restart during deployments and that your performance metrics persist through scheduled snapshots. This guide walks through the automated and manual steps to sync these powerful tools.
Prerequisites
Before proceeding, ensure you have a server provisioned via Laravel Forge and a repository deployed. You should have Laravel Horizon already installed in your application via Composer and its configuration file published.
Key Libraries & Tools
- Laravel Horizon: A monitoring tool that provides a dashboard for Redis-powered Laravel queues.
- Laravel Forge: A server management platform for deploying and scaling PHP applications.
- Artisan: The command-line interface included with Laravel.
- Redis: The in-memory data structure store used as the queue backend.
Code Walkthrough
To keep Laravel Horizon healthy, you must update your deployment script in the Laravel Forge UI. Add the following command to ensure the process restarts whenever you push new code:
# Forge Deployment Script
php artisan horizon:terminate
This command signals the current Laravel Horizon master process to terminate after it finishes its current jobs. Laravel Forge then automatically restarts it via a daemon, ensuring your workers always run the latest version of your code.
Enabling Metrics with the Scheduler
Laravel Horizon features a metrics dashboard that tracks job throughput and wait times. This data requires the horizon:snapshot command to run every five minutes. To handle this, ensure your routes/console.php or app/Console/Kernel.php contains the scheduled task, then enable the Laravel Scheduler in Laravel Forge.
// routes/console.php
use Illuminate\Support\Facades\Schedule;
Schedule::command('horizon:snapshot')->everyFiveMinutes();
Syntax Notes
The horizon:terminate command is preferred over simply killing the process because it allows for "graceful" termination. It respects the timeout settings in your config/horizon.php, ensuring jobs aren't hard-killed mid-execution.
Tips & Gotchas
- Daemons: When you toggle the Laravel Horizon switch in Laravel Forge, it creates a system daemon. Do not manually create a separate worker daemon for the same queue, as they will conflict.
- Snapshotting: If your metrics dashboard is empty, verify the Laravel Scheduler is active. Without
artisan schedule:runactive in your system's crontab, Laravel Horizon cannot record the state of your queues.
- Laravel Horizon
- 37%· products
- Laravel Forge
- 32%· products
- Laravel
- 21%· products
- Dev Harper
- 5%· people
- GitHub
- 5%· products

Setup Laravel Horizon on Forge
WatchLaravel // 3:03
The official YouTube channel of Laravel, the clean stack for Artisans and agents. We will update you on what's new in the world of Laravel, from the framework to our products Cloud, Forge, and Nightwatch.