Skip to main content

What is Horizon?

Laravel Horizon provides a beautiful dashboard and code-driven configuration for Laravel Redis queues. It lets you monitor job throughput, runtime, and failures in real time while managing all worker configuration in a single version-controlled file.
Horizon extends Laravel’s core queue system. Make sure you are familiar with Queues & Jobs before proceeding. A running Redis instance is also required.

Installation

Horizon requires Redis as the queue backend. Ensure QUEUE_CONNECTION=redis is set in your .env file. Horizon is not compatible with Redis Cluster at this time.
Install Horizon via Composer:
Publish Horizon’s assets and configuration:
This generates config/horizon.php and app/Providers/HorizonServiceProvider.php.

Configuration

config/horizon.php overview

All worker configuration lives in config/horizon.php. The core option is environments, which defines worker process options per environment.
Horizon reserves the horizon Redis connection name internally. Do not assign this name to another connection in config/database.php.

Supervisors

Each environment can contain one or more supervisors. A supervisor manages a group of worker processes and handles balancing across queues. You can define multiple supervisors per environment to apply different strategies to different queues.

Default values

Use the defaults option to specify configuration values shared across all supervisors, reducing repetition.

Maintenance mode

When the application is in maintenance mode, Horizon stops processing jobs by default. To force processing, set force to true:

Max job attempts

Setting tries to 0 allows unlimited attempts.

Job timeout

The timeout value should always be at least a few seconds shorter than the retry_after value in config/queue.php. When using the auto balance strategy, Horizon force-kills workers that exceed the timeout during scale-down.

Job backoff

Specify how long Horizon waits before retrying a job that encountered an exception.

Balancing strategies

Horizon offers three worker balancing strategies.
Automatically adjusts the number of worker processes per queue based on current workload. Configure the range with minProcesses and maxProcesses.
  • time — scales based on estimated time to clear the queue
  • size — scales based on number of jobs in the queue
With auto balancing, queue order does not imply priority. Use multiple supervisors with explicit resource limits to enforce priorities.
Distributes a fixed number of worker processes evenly across the specified queues.
The example above assigns 5 processes to each queue.
Processes queues strictly in the listed order, similar to Laravel’s default queue system. Horizon still scales worker count as jobs accumulate.
Jobs in default are always processed before notifications.

Dashboard authorization

The Horizon dashboard is accessible at /horizon. In local environments, it is open to everyone by default. In non-local environments, access is controlled by the authorization gate in app/Providers/HorizonServiceProvider.php.
If you secure Horizon via IP restrictions rather than authentication, make the user argument optional:

Running Horizon

Artisan commands

Auto-restart during development

Use horizon:listen to automatically restart Horizon when files change.

Keeping Horizon running with Supervisor

In production, use Supervisor to ensure Horizon restarts automatically if it stops.

Install Supervisor

Supervisor configuration

Create /etc/supervisor/conf.d/horizon.conf:
Set stopwaitsecs to a value greater than your longest-running job’s duration. Otherwise Supervisor will kill the job before it finishes.

Start Supervisor

On deployment

Terminate Horizon during each deployment so the process monitor restarts it with your new code:
With autostart=true and autorestart=true in the Supervisor config, Horizon will start back up automatically.

Managing jobs

Tags

Horizon automatically tags jobs based on the Eloquent models they receive.
Define custom tags by implementing a tags() method on the job:
For queued event listeners, the event instance is automatically passed to tags():

Silencing jobs

Hide specific jobs from the “Completed Jobs” list by adding them to the silenced option in config/horizon.php.
Alternatively, implement the Silenced interface directly on the job class:

Metrics and monitoring

Horizon’s metrics dashboard shows job and queue throughput and wait times. Schedule the horizon:snapshot command to populate it.
Clear all metric data with:

Job failure notifications

Receive notifications when a queue’s wait time exceeds a threshold. Configure notification recipients in the boot() method of app/Providers/HorizonServiceProvider.php.

Wait time thresholds

Configure how many seconds constitute a “long wait” in config/horizon.php:
Setting a threshold to 0 disables notifications for that queue.

Managing failed jobs

Delete a specific failed job by ID or UUID:
Clear all pending jobs from a queue:

Upgrading Horizon

When upgrading to a new major version, review the Horizon upgrade guide carefully.

Queues & Jobs

Laravel queue fundamentals: job creation, dispatch, batches, and failed job handling.

Redis

Configure and use Redis — the required backend for Horizon.
Last modified on April 13, 2026