Skip to main content

What is Horizon?

Laravel Horizon is a monitoring dashboard dedicated to Laravel’s Redis queue. You can visualize job throughput, run time, and failure state in real time and manage your worker configuration in code.
Horizon is a package that extends the base queue features. Make sure you understand the fundamentals of queues and jobs before reading on. You must also use Redis as the backend.

Installation

Horizon uses Redis as its queue backend. Make sure QUEUE_CONNECTION in config/queue.php is set to redis. Redis Cluster is not currently supported.
Install via Composer.
After installation, publish Horizon’s assets and configuration files.
This command generates config/horizon.php and app/Providers/HorizonServiceProvider.php.

Configuration

Structure of config/horizon.php

config/horizon.php is the file that manages all worker configuration. The core option is environments.
Horizon internally uses a Redis connection named horizon. Do not use this name for any other connection in config/database.php.

CSP nonce (Content Security Policy)

If you want to set a nonce attribute on the script / style tags used in Horizon’s views as part of a Content Security Policy, use the Horizon::cspNonce method. Since a new nonce is assigned per request, you’ll typically call this inside a middleware.
Add this middleware to the middleware option in config/horizon.php.

Supervisors

Each environment can have one or more “supervisors”. A supervisor is a management unit for a worker group; you can run multiple supervisors with different queues, balance strategies, and process counts inside the same environment.

Default values

Use the defaults option to configure default values that apply to every supervisor.

Maintenance mode

When your application is in maintenance mode, Horizon does not process jobs by default. To force processing, use the force option.

Maximum number of attempts

Setting tries to 0 allows unlimited retries.

Job timeout

Set timeout to a value a few seconds shorter than retry_after in config/queue.php. Also, the auto balance strategy may forcibly terminate jobs that run longer than this value.

Backoff (wait time before retry)

Specify the number of seconds to wait before retrying after an exception.

Other worker options

In addition to tries, timeout, and backoff, each supervisor accepts options that control worker process behavior and when workers should automatically restart. Periodically restarting long-running processes is a good practice for preventing memory leaks.
  • memory — the maximum memory (MB) a worker process can consume before restarting. Defaults to 128.
  • maxJobs — the number of jobs to process before restarting. 0 means unlimited. Defaults to 0.
  • maxTime — the number of seconds a worker can run before restarting. 0 means no time-based restart. Defaults to 0.
  • sleep — seconds to wait before polling for the next job when the queue is empty. Defaults to 3.
  • rest — seconds to pause between each job. Defaults to 0.
  • nice — the priority (“niceness”) of the worker process. Higher values mean lower priority. Defaults to 0.

Balance strategies

Horizon provides three worker balance strategies.
Automatically adjusts the number of workers based on queue load. Use minProcesses and maxProcesses to define the range.
  • time — scales based on the estimated time to drain the queue.
  • size — scales based on the number of jobs in the queue.
Under the auto strategy, queue order does not indicate priority. If you need to enforce priority, use multiple supervisors.
Uses a fixed number of workers and distributes them evenly across the configured queues.
In the example above, five processes each are assigned to default and notifications.
Strictly prioritizes queues in the order listed. Behavior is similar to Laravel’s default queue system, but Horizon scales worker count based on backlog.
Jobs on the default queue are always processed before jobs on notifications.

Dashboard authorization

Horizon’s dashboard is accessible at the /horizon route. In the local environment, anyone can access it by default, but in production you should restrict access via a gate. Edit the gate() method in app/Providers/HorizonServiceProvider.php.
If authentication isn’t required (for example, when you protect it via IP restriction), make the argument optional.

Starting Horizon

Basic commands

Local development: auto restart

Use the horizon:listen command to detect file changes and automatically restart Horizon.

Continuous operation with Supervisor

In production, use Supervisor to keep Horizon running.

Installing Supervisor

Creating the config file

Create /etc/supervisor/conf.d/horizon.conf.
Set stopwaitsecs to a value larger than your longest-running job. Setting it too low will cause Supervisor to forcibly terminate jobs mid-flight.

Starting Supervisor

On deploy

Restart Horizon on every code deploy so your changes take effect.
As long as Supervisor is configured with autostart=true / autorestart=true, it will restart Horizon automatically after termination.

Managing jobs

Tags

Horizon automatically detects Eloquent models related to a job and adds them as tags.
To define tags manually, implement the tags() method.
For event listeners, the event instance is passed to tags().

Silencing

You can silence jobs you don’t want shown in the “Completed Jobs” list on the dashboard by configuring config/horizon.php.
You can also implement the Silenced interface.

Metrics and monitoring

Horizon’s metrics dashboard shows job and queue throughput and run time. Schedule regular snapshots to keep the data up to date.
The metrics.trim_snapshots option in config/horizon.php controls how many snapshots to keep for the metrics graphs. This setting limits by count rather than age, so the actual retention period depends on how often you run horizon:snapshot.
To delete all metrics data, run:

Notifications on job failure

You can be notified when queue wait times grow long. Configure this in the boot() method of app/Providers/HorizonServiceProvider.php.

Wait time thresholds

Configure the seconds of waiting that trigger notifications with the waits option in config/horizon.php.
Setting a value to 0 disables notifications for that queue.

Managing failed jobs

You can delete failed jobs by ID or UUID.
To clear every job on a queue, use:

Upgrading

Always check the upgrade guide when upgrading Horizon to a major version.

Queues and jobs

The basics of Laravel queues — creating and dispatching jobs, batching, and handling failures.

Redis

Configuring and using the Redis backend that Horizon requires.
Last modified on August 2, 2026