> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel Horizon

> Leer hoe je Redis-queues visueel beheert en monitort met Laravel Horizon. Behandelt het dashboard, balanceerstrategieën, Supervisor-configuratie en notificaties.

## Wat is Horizon

[Laravel Horizon](https://github.com/laravel/horizon) is een monitoringdashboard **speciaal voor Redis-queues** in Laravel. Het visualiseert de doorvoer, uitvoeringstijd en mislukkingen van jobs in realtime en laat je de workerconfiguratie in code beheren.

<Info>
  Horizon is een pakket dat de basisfunctionaliteit van queues uitbreidt. Zorg dat je eerst de basis van [Queues en jobs](/nl/queues) begrijpt voordat je verder leest. Voor de backend is bovendien altijd [Redis](/nl/redis) nodig.
</Info>

```mermaid theme={null}
flowchart LR
    Browser["Browser"] -->|"/horizon"| Dashboard["Horizon-<br>dashboard"]
    Dashboard -->|"Monitoren en aansturen"| Horizon["Horizon-<br>proces"]
    Horizon -->|"Jobbeheer"| Redis["Redis<br>Queue"]
    Redis -->|"Job ophalen"| Worker1["Worker 1"]
    Redis -->|"Job ophalen"| Worker2["Worker 2"]
    Redis -->|"Job ophalen"| Worker3["Worker 3"]
```

## Installatie

<Warning>
  Horizon gebruikt Redis als queuebackend. Controleer dat `QUEUE_CONNECTION` in `config/queue.php` is ingesteld op `redis`. Redis Cluster wordt momenteel niet ondersteund.
</Warning>

Installeer met Composer.

```shell theme={null}
composer require laravel/horizon
```

Publiceer na de installatie de assets en het configuratiebestand van Horizon.

```shell theme={null}
php artisan horizon:install
```

Dit commando genereert `config/horizon.php` en `app/Providers/HorizonServiceProvider.php`.

## Configuratie

### Opbouw van config/horizon.php

`config/horizon.php` is het bestand waarin alle workerconfiguratie wordt beheerd. De kern is de optie `environments`.

```php theme={null}
'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' => [
            // De overige waarden worden overgenomen uit de sectie defaults
            'maxProcesses' => 3,
        ],
    ],
],
```

<Info>
  Horizon gebruikt intern een Redis-verbinding met de naam `horizon`. Gebruik deze naam in `config/database.php` niet voor een andere verbinding.
</Info>

### CSP-nonce (Content Security Policy)

Wil je als onderdeel van je [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) een [nonce-attribuut](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce) instellen op de `script`- en `style`-tags in de views van Horizon, gebruik dan de methode `Horizon::cspNonce`. Omdat je per request een nieuwe nonce wilt toewijzen, roep je die meestal aan in een middleware.

```php theme={null}
use Closure;
use Illuminate\Http\Request;
use Laravel\Horizon\Horizon;
use Symfony\Component\HttpFoundation\Response;

public function handle(Request $request, Closure $next): Response
{
    Horizon::cspNonce('csp-nonce');

    return $next($request);
}
```

Voeg deze middleware toe aan de optie `middleware` in `config/horizon.php`.

```php theme={null}
'middleware' => [
    'web',
    App\Http\Middleware\AddHorizonCspNonce::class,
],
```

### Supervisors

Elke omgeving kan één of meer "supervisors" hebben. Een supervisor is de beheereenheid voor een groep workers; je kunt in dezelfde omgeving meerdere supervisors draaien met verschillende queues, balanceerstrategieën en procesaantallen.

### Standaardwaarden

Met de optie `defaults` stel je standaardwaarden in die op alle supervisors worden toegepast.

```php theme={null}
'defaults' => [
    'supervisor-1' => [
        'connection' => 'redis',
        'queue' => ['default'],
        'balance' => 'auto',
        'tries' => 1,
        'timeout' => 60,
        'maxProcesses' => 1,
    ],
],
```

### Onderhoudsmodus

Wanneer de applicatie in onderhoudsmodus staat, verwerkt Horizon standaard geen jobs. Wil je jobs toch geforceerd laten verwerken, gebruik dan de optie `force`.

```php theme={null}
'environments' => [
    'production' => [
        'supervisor-1' => [
            'force' => true,
        ],
    ],
],
```

### Maximaal aantal pogingen per job

```php theme={null}
'environments' => [
    'production' => [
        'supervisor-1' => [
            'tries' => 10,
        ],
    ],
],
```

Zet je `tries` op `0`, dan zijn onbeperkte nieuwe pogingen toegestaan.

### Jobtimeout

```php theme={null}
'environments' => [
    'production' => [
        'supervisor-1' => [
            'timeout' => 60,
        ],
    ],
],
```

<Warning>
  Stel `timeout` een paar seconden korter in dan `retry_after` in `config/queue.php`. Bovendien kan de `auto`-balanceerstrategie jobs die langer duren dan deze waarde geforceerd beëindigen.
</Warning>

### Backoff (wachttijd voor nieuwe pogingen)

Geeft het aantal seconden op dat wordt gewacht voordat na een exceptie een nieuwe poging wordt gedaan.

```php theme={null}
// Vaste waarde
'backoff' => 10,

// Stapsgewijs (exponentiële backoff)
'backoff' => [1, 5, 10],
```

### Overige workeropties

Naast `tries`, `timeout` en `backoff` accepteert elke supervisor opties die het gedrag van de workerprocessen en het moment van automatisch herstarten bepalen. Langlopende processen regelmatig herstarten is een goede gewoonte om geheugenlekken te voorkomen.

```php theme={null}
'environments' => [
    'production' => [
        'supervisor-1' => [
            // ...
            'memory' => 128,
            'maxJobs' => 1000,
            'maxTime' => 3600,
            'sleep' => 3,
            'rest' => 0,
            'nice' => 0,
        ],
    ],
],
```

* `memory` — de maximale hoeveelheid geheugen (MB) die een workerproces mag verbruiken voordat het wordt herstart. Standaard `128`
* `maxJobs` — het aantal jobs dat wordt verwerkt voordat het proces wordt herstart. `0` betekent onbeperkt. Standaard `0`
* `maxTime` — het aantal seconden dat een worker mag draaien voordat hij wordt herstart. `0` betekent geen herstart op basis van tijd. Standaard `0`
* `sleep` — het aantal seconden dat wordt gewacht tot de volgende poll wanneer er geen jobs zijn. Standaard `3`
* `rest` — het aantal seconden pauze tussen het verwerken van jobs. Standaard `0`
* `nice` — de prioriteit ("niceness") van het workerproces. Hoe hoger de waarde, hoe lager de prioriteit. Standaard `0`

## Balanceerstrategieën

Horizon kent drie balanceerstrategieën voor workers.

<AccordionGroup>
  <Accordion title="auto (standaard)">
    Past het aantal workers automatisch aan op basis van de belasting van de queues. Met `minProcesses` en `maxProcesses` geef je het bereik op.

    ```php theme={null}
    'supervisor-1' => [
        'balance' => 'auto',
        'autoScalingStrategy' => 'time', // of 'size'
        'minProcesses' => 1,
        'maxProcesses' => 10,
        'balanceMaxShift' => 1,
        'balanceCooldown' => 3,
    ],
    ```

    * `time` — schalen op basis van de geschatte tijd om de queue leeg te maken
    * `size` — schalen op basis van het aantal jobs in de queue

    <Info>
      Bij de `auto`-strategie betekent de volgorde van de queues geen prioriteit. Wil je prioriteit afdwingen, gebruik dan meerdere supervisors.
    </Info>
  </Accordion>

  <Accordion title="simple">
    Houdt het aantal workers vast en verdeelt ze gelijkmatig over de opgegeven queues.

    ```php theme={null}
    'supervisor-1' => [
        'balance' => 'simple',
        'processes' => 10,
        'queue' => ['default', 'notifications'],
    ],
    ```

    In het bovenstaande voorbeeld krijgen `default` en `notifications` elk vijf processen toegewezen.
  </Accordion>

  <Accordion title="false (geen balancering)">
    Geeft strikt prioriteit aan de queues in de volgorde waarin ze zijn opgesomd. Dit gedraagt zich zoals het standaard queuesysteem van Laravel, maar schaalt het aantal workers op basis van de achterstand.

    ```php theme={null}
    'supervisor-1' => [
        'balance' => false,
        'queue' => ['default', 'notifications'],
        'minProcesses' => 1,
        'maxProcesses' => 10,
    ],
    ```

    Jobs in de `default`-queue worden altijd vóór die in de `notifications`-queue verwerkt.
  </Accordion>
</AccordionGroup>

## Autorisatie van het dashboard

Het Horizon-dashboard bereik je via de route `/horizon`. In een lokale omgeving is het standaard voor iedereen toegankelijk, maar in **productie** beperk je de toegang met een gate-definitie.

Bewerk de methode `gate()` in `app/Providers/HorizonServiceProvider.php`.

```php theme={null}
use App\Models\User;
use Illuminate\Support\Facades\Gate;

protected function gate(): void
{
    Gate::define('viewHorizon', function (User $user) {
        return in_array($user->email, [
            'admin@example.com',
        ]);
    });
}
```

Is authenticatie niet nodig (bijvoorbeeld omdat je met IP-restricties beschermt), maak het argument dan optioneel.

```php theme={null}
Gate::define('viewHorizon', function (User $user = null) {
    // Wanneer je de toegang beperkt via IP-adressen e.d.
    return true;
});
```

## Horizon starten

### Basiscommando's

```shell theme={null}
# Starten
php artisan horizon

# Pauzeren / hervatten
php artisan horizon:pause
php artisan horizon:continue

# Een specifieke supervisor pauzeren / hervatten
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1

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

# Netjes afsluiten
php artisan horizon:terminate
```

### Lokale ontwikkeling: automatisch herstarten

Om Horizon automatisch te herstarten bij bestandswijzigingen gebruik je het commando `horizon:listen`.

```shell theme={null}
npm install --save-dev chokidar
php artisan horizon:listen

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

### Continu draaien met Supervisor

In productie houd je Horizon continu draaiend met Supervisor.

#### Supervisor installeren

```shell theme={null}
sudo apt-get install supervisor
```

#### Het configuratiebestand aanmaken

Maak `/etc/supervisor/conf.d/horizon.conf` aan.

```ini theme={null}
[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
```

<Warning>
  Stel `stopwaitsecs` in op een waarde die groter is dan de uitvoeringstijd van je langste job. Is de waarde te klein, dan beëindigt Supervisor jobs halverwege geforceerd.
</Warning>

#### Supervisor starten

```shell theme={null}
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start horizon
```

#### Bij het deployen

Herstart Horizon bij elke code-deploy om de wijzigingen door te voeren.

```shell theme={null}
php artisan horizon:terminate
```

Staan `autostart=true` / `autorestart=true` in Supervisor, dan wordt Horizon na het afsluiten automatisch opnieuw gestart.

## Jobbeheer

### Tags

Horizon detecteert automatisch de Eloquent-modellen die aan een job zijn gekoppeld en voegt tags toe.

```php theme={null}
// Een job die een Video-model (id=1) ontvangt → krijgt automatisch de tag "App\Models\Video:1"
RenderVideo::dispatch(Video::find(1));
```

Wil je tags handmatig definiëren, implementeer dan de methode `tags()`.

```php theme={null}
class RenderVideo implements ShouldQueue
{
    /**
     * @return array<int, string>
     */
    public function tags(): array
    {
        return ['render', 'video:'.$this->video->id];
    }
}
```

Bij event listeners wordt de eventinstantie doorgegeven aan de methode `tags()`.

```php theme={null}
class SendRenderNotifications implements ShouldQueue
{
    public function tags(VideoRendered $event): array
    {
        return ['video:'.$event->video->id];
    }
}
```

### Silencen

Jobs die je niet wilt tonen in de lijst "voltooide jobs" van het dashboard kun je silencen in `config/horizon.php`.

```php theme={null}
'silenced' => [
    App\Jobs\ProcessPodcast::class,
],

// Silencen per tag
'silenced_tags' => [
    'notifications',
],
```

Je kunt ook de interface `Silenced` implementeren.

```php theme={null}
use Laravel\Horizon\Contracts\Silenced;

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

## Metrics en monitoring

Het metricsdashboard van Horizon toont de doorvoer en uitvoeringstijd van jobs en queues. Stel een schedule in om regelmatig snapshots te maken.

```php theme={null}
// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('horizon:snapshot')->everyFiveMinutes();
```

Met de optie `metrics.trim_snapshots` in `config/horizon.php` stel je in hoeveel snapshots er worden bewaard voor de metricsgrafieken. Deze instelling begrenst het aantal snapshots, niet hun leeftijd; de daadwerkelijke bewaartermijn hangt dus af van hoe vaak het commando `horizon:snapshot` draait.

```php theme={null}
'metrics' => [
    'trim_snapshots' => [
        'job' => 24,
        'queue' => 24,
    ],
],
```

Om alle metricsdata te verwijderen voer je dit uit:

```shell theme={null}
php artisan horizon:clear-metrics
```

## Notificaties bij mislukte jobs

Je kunt een notificatie ontvangen wanneer de wachttijd van een queue oploopt. Configureer dit in de methode `boot()` van `app/Providers/HorizonServiceProvider.php`.

```php theme={null}
use Laravel\Horizon\Horizon;

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

    Horizon::routeMailNotificationsTo('admin@example.com');
    Horizon::routeSlackNotificationsTo('slack-webhook-url', '#ops');
    Horizon::routeSmsNotificationsTo('15556667777');
}
```

### Drempelwaarden voor wachttijden

Met de optie `waits` in `config/horizon.php` stel je het aantal seconden wachttijd in dat een notificatie activeert.

```php theme={null}
'waits' => [
    'redis:critical' => 30,  // Notificatie bij 30 seconden of meer wachttijd
    'redis:default' => 60,
    'redis:batch' => 120,
],
```

Stel je `0` in, dan zijn notificaties voor die queue uitgeschakeld.

## Mislukte jobs beheren

Mislukte jobs kun je verwijderen op ID of UUID.

```shell theme={null}
# Een specifieke mislukte job verwijderen
php artisan horizon:forget 5

# Alle mislukte jobs verwijderen
php artisan horizon:forget --all
```

Om alle jobs uit een queue te wissen gebruik je het volgende:

```shell theme={null}
# De standaardqueue wissen
php artisan horizon:clear

# Een specifieke queue wissen
php artisan horizon:clear --queue=emails
```

## Upgraden

Raadpleeg bij een major-versie-upgrade van Horizon altijd de [upgradegids](https://github.com/laravel/horizon/blob/master/UPGRADE.md).

## Gerelateerde pagina's

<CardGroup cols={2}>
  <Card title="Queues en jobs" href="/nl/queues">
    De basis van Laravel-queues. Behandelt het aanmaken, dispatchen, batchen en afhandelen van mislukte jobs.
  </Card>

  <Card title="Redis" href="/nl/redis">
    De configuratie en het gebruik van Redis, dat als backend voor Horizon nodig is.
  </Card>
</CardGroup>


## Related topics

- [Cache](/nl/cache.md)
- [Versiecompatibiliteit van packages beheren](/nl/advanced/package-versioning.md)
- [Queues en jobs](/nl/queues.md)
- [Laravel Sentinel — verkenning van de routebeschermings-middleware](/nl/blog/sentinel-introduction.md)
- [Laravel-updates van april 2026](/nl/blog/changelog/202604.md)
