Zum Hauptinhalt springen

Was ist Horizon?

Laravel Horizon ist ein Überwachungs-Dashboard speziell für Redis-Queues in Laravel. Es visualisiert Job-Durchsatz, Laufzeiten und Fehler in Echtzeit und ermöglicht es, Worker-Einstellungen im Code zu verwalten.
Horizon erweitert die Basisfunktionalität der Queue. Machen Sie sich zunächst mit den Grundlagen zu Queues und Jobs vertraut. Als Backend ist zwingend Redis erforderlich.

Installation

Horizon nutzt Redis als Queue-Backend. Stellen Sie sicher, dass QUEUE_CONNECTION in config/queue.php auf redis gesetzt ist. Redis Cluster wird derzeit nicht unterstützt.
Installation via Composer:
composer require laravel/horizon
Veröffentlichen Sie anschließend die Assets und die Konfigurationsdatei.
php artisan horizon:install
Dabei werden config/horizon.php und app/Providers/HorizonServiceProvider.php erzeugt.

Konfiguration

Aufbau der Datei config/horizon.php

config/horizon.php bündelt sämtliche Worker-Einstellungen. Kern ist die Option environments.
'environments' => [
    'production' => [
        'supervisor-1' => [
            'connection' => 'redis',
            'queue' => ['default', 'notifications'],
            'balance' => 'auto',
            'autoScalingStrategy' => 'time',
            'minProcesses' => 1,
            'maxProcesses' => 10,
            'balanceMaxShift' => 1,
            'balanceCooldown' => 3,
            'tries' => 3,
            'timeout' => 60,
        ],
    ],

    'local' => [
        'supervisor-1' => [
            // Weitere Werte werden aus dem defaults-Bereich übernommen
            'maxProcesses' => 3,
        ],
    ],
],
Horizon nutzt intern eine Redis-Verbindung namens horizon. Vergeben Sie diesen Namen in config/database.php nicht an eine andere Verbindung.

Supervisor

Jede Umgebung kann einen oder mehrere „Supervisor” enthalten. Ein Supervisor ist die Verwaltungseinheit für eine Worker-Gruppe; Sie können pro Umgebung mehrere Supervisor mit unterschiedlichen Queues, Balance-Strategien und Prozessanzahlen betreiben.

Standardwerte

In defaults legen Sie Standardwerte fest, die für alle Supervisor gelten.
'defaults' => [
    'supervisor-1' => [
        'connection' => 'redis',
        'queue' => ['default'],
        'balance' => 'auto',
        'tries' => 1,
        'timeout' => 60,
        'maxProcesses' => 1,
    ],
],

Wartungsmodus

Ist die Anwendung im Wartungsmodus, verarbeitet Horizon standardmäßig keine Jobs. Um die Verarbeitung dennoch zu erzwingen, verwenden Sie die Option force.
'environments' => [
    'production' => [
        'supervisor-1' => [
            'force' => true,
        ],
    ],
],

Maximale Anzahl an Versuchen

'environments' => [
    'production' => [
        'supervisor-1' => [
            'tries' => 10,
        ],
    ],
],
Mit tries auf 0 erlauben Sie unbegrenzte Wiederholungen.

Job-Timeout

'environments' => [
    'production' => [
        'supervisor-1' => [
            'timeout' => 60,
        ],
    ],
],
Setzen Sie timeout einige Sekunden kürzer als retry_after in config/queue.php. Mit der Balance-Strategie auto beendet Horizon zudem Jobs, die diesen Wert überschreiten, gegebenenfalls zwangsweise.

Backoff (Wartezeit vor Wiederholung)

Wartezeit in Sekunden nach einer Ausnahme bis zum nächsten Versuch.
// Fester Wert
'backoff' => 10,

// Gestaffelt (exponentielles Backoff)
'backoff' => [1, 5, 10],

Balance-Strategien

Horizon kennt drei Strategien zur Worker-Balancierung.
Passt die Worker-Anzahl automatisch an die Queue-Auslastung an. Über minProcesses und maxProcesses bestimmen Sie den Rahmen.
'supervisor-1' => [
    'balance' => 'auto',
    'autoScalingStrategy' => 'time', // oder 'size'
    'minProcesses' => 1,
    'maxProcesses' => 10,
    'balanceMaxShift' => 1,
    'balanceCooldown' => 3,
],
  • time – Skalierung nach geschätzter Zeit bis zur Leerung der Queue
  • size – Skalierung nach Anzahl der Jobs in der Queue
Bei der Strategie auto bestimmt die Reihenfolge der Queues nicht deren Priorität. Für strikte Prioritäten verwenden Sie mehrere Supervisor.
Legt eine feste Anzahl Worker fest und verteilt sie gleichmäßig auf die angegebenen Queues.
'supervisor-1' => [
    'balance' => 'simple',
    'processes' => 10,
    'queue' => ['default', 'notifications'],
],
Im Beispiel erhalten default und notifications jeweils fünf Prozesse.
Priorisiert die Queues strikt in der angegebenen Reihenfolge. Das Verhalten entspricht dem Standard-Queue-System, skaliert die Worker-Anzahl aber dennoch bedarfsabhängig.
'supervisor-1' => [
    'balance' => false,
    'queue' => ['default', 'notifications'],
    'minProcesses' => 1,
    'maxProcesses' => 10,
],
Jobs der Queue default werden immer vor denen der Queue notifications verarbeitet.

Autorisierung des Dashboards

Das Horizon-Dashboard ist unter der Route /horizon erreichbar. Lokal ist es standardmäßig für alle zugänglich; in der Produktion schränken Sie den Zugriff über ein Gate ein. Passen Sie die Methode gate() in app/Providers/HorizonServiceProvider.php an.
use App\Models\User;
use Illuminate\Support\Facades\Gate;

protected function gate(): void
{
    Gate::define('viewHorizon', function (User $user) {
        return in_array($user->email, [
            '[email protected]',
        ]);
    });
}
Ist keine Authentifizierung erforderlich (weil Sie z. B. IP-Einschränkungen nutzen), machen Sie das Argument optional.
Gate::define('viewHorizon', function (User $user = null) {
    // Wenn der Zugriff z. B. per IP-Adresse eingeschränkt wird
    return true;
});

Horizon starten

Grundlegende Befehle

# Starten
php artisan horizon

# Pausieren / fortsetzen
php artisan horizon:pause
php artisan horizon:continue

# Bestimmten Supervisor pausieren / fortsetzen
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1

# Status abfragen
php artisan horizon:status
php artisan horizon:supervisor-status supervisor-1

# Sauber beenden
php artisan horizon:terminate

Lokale Entwicklung: automatisches Neustarten

Um Horizon bei Änderungen an Quellcode automatisch neu zu starten, verwenden Sie horizon:listen.
npm install --save-dev chokidar
php artisan horizon:listen

# In Docker- / Vagrant-Umgebungen
php artisan horizon:listen --poll

Dauerbetrieb mit Supervisor

In der Produktion betreiben Sie Horizon mit Supervisor dauerhaft.

Supervisor installieren

sudo apt-get install supervisor

Konfigurationsdatei anlegen

Legen Sie /etc/supervisor/conf.d/horizon.conf an.
[program:horizon]
process_name=%(program_name)s
command=php /home/forge/example.com/artisan horizon
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/example.com/horizon.log
stopwaitsecs=3600
Setzen Sie stopwaitsecs höher als die längste erwartete Jobdauer. Ist der Wert zu klein, kann Supervisor Jobs abbrechen, bevor sie fertig sind.

Supervisor starten

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start horizon

Beim Deployment

Starten Sie Horizon nach jedem Deployment neu, damit Änderungen greifen.
php artisan horizon:terminate
Sofern Supervisor mit autostart=true und autorestart=true konfiguriert ist, startet Horizon anschließend automatisch neu.

Jobs verwalten

Tags

Horizon erkennt Eloquent-Modelle, die einem Job übergeben werden, automatisch und versieht Jobs mit passenden Tags.
// Job mit Video-Modell (id=1) → automatischer Tag "App\Models\Video:1"
RenderVideo::dispatch(Video::find(1));
Um Tags manuell zu definieren, implementieren Sie die Methode tags().
class RenderVideo implements ShouldQueue
{
    /**
     * @return array<int, string>
     */
    public function tags(): array
    {
        return ['render', 'video:'.$this->video->id];
    }
}
Bei Event-Listenern wird der Methode tags() die Event-Instanz übergeben.
class SendRenderNotifications implements ShouldQueue
{
    public function tags(VideoRendered $event): array
    {
        return ['video:'.$event->video->id];
    }
}

Ausblenden (Silence)

Jobs, die nicht in der Liste „abgeschlossener Jobs” im Dashboard erscheinen sollen, können Sie in config/horizon.php ausblenden.
'silenced' => [
    App\Jobs\ProcessPodcast::class,
],

// Nach Tags ausblenden
'silenced_tags' => [
    'notifications',
],
Alternativ implementieren Sie das Interface Silenced.
use Laravel\Horizon\Contracts\Silenced;

class ProcessPodcast implements ShouldQueue, Silenced
{
    use Queueable;
    // ...
}

Metriken und Monitoring

Das Metrik-Dashboard von Horizon zeigt den Durchsatz und die Laufzeit von Jobs und Queues. Damit die Daten fortlaufend aktualisiert werden, richten Sie einen Snapshot-Zeitplan ein.
// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('horizon:snapshot')->everyFiveMinutes();
Um alle Metrikdaten zu löschen, führen Sie folgenden Befehl aus:
php artisan horizon:clear-metrics

Benachrichtigungen zu Job-Fehlern

Bei langen Wartezeiten in der Queue können Sie sich benachrichtigen lassen. Konfigurieren Sie dies in der boot()-Methode von app/Providers/HorizonServiceProvider.php.
use Laravel\Horizon\Horizon;

public function boot(): void
{
    parent::boot();

    Horizon::routeMailNotificationsTo('[email protected]');
    Horizon::routeSlackNotificationsTo('slack-webhook-url', '#ops');
    Horizon::routeSmsNotificationsTo('15556667777');
}

Schwellenwerte für Wartezeiten

In config/horizon.php legen Sie mit der Option waits die Wartezeit fest, ab der Benachrichtigungen gesendet werden.
'waits' => [
    'redis:critical' => 30,  // Benachrichtigen ab 30 Sekunden Wartezeit
    'redis:default' => 60,
    'redis:batch' => 120,
],
Der Wert 0 deaktiviert die Benachrichtigung für die betreffende Queue.

Umgang mit fehlgeschlagenen Jobs

Fehlgeschlagene Jobs können Sie über ID oder UUID löschen.
# Bestimmten fehlgeschlagenen Job löschen
php artisan horizon:forget 5

# Alle fehlgeschlagenen Jobs löschen
php artisan horizon:forget --all
Um alle Jobs einer Queue zu löschen, verwenden Sie:
# Standard-Queue leeren
php artisan horizon:clear

# Bestimmte Queue leeren
php artisan horizon:clear --queue=emails

Upgrades

Vor einem Major-Update von Horizon sollten Sie stets die Upgrade-Anleitung lesen.

Verwandte Seiten

Queues und Jobs

Grundlagen der Laravel-Queue: Job-Erstellung, Dispatchen, Batches und Fehlerbehandlung.

Redis

Konfiguration und Nutzung von Redis als Backend für Horizon.
Zuletzt geändert am 13. Juli 2026