Configuring Laravel Horizon on Laravel Forge: A Seamless Queue Strategy

Overview

Efficient queue management defines modern PHP applications.

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

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

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

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

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:run active in your system's crontab,
    Laravel Horizon
    cannot record the state of your queues.
3 min read