> ## 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

> Come gestire e monitorare visivamente le code Redis con Laravel Horizon. Dashboard, strategie di bilanciamento, configurazione Supervisor e notifiche.

## Cos'è Horizon

[Laravel Horizon](https://github.com/laravel/horizon) è la dashboard di monitoraggio **dedicata alle code Redis** di Laravel. Visualizza in tempo reale throughput, tempi di esecuzione e fallimenti dei job e gestisci la configurazione dei worker via codice.

<Info>
  Horizon estende le funzionalità di base delle code. Consulta prima [Code e job](/it/queues) e assicurati che sia disponibile [Redis](/it/redis).
</Info>

```mermaid theme={null}
flowchart LR
    Browser["Browser"] -->|"/horizon"| Dashboard["Dashboard<br>Horizon"]
    Dashboard -->|"Monitoraggio/Controllo"| Horizon["Processo<br>Horizon"]
    Horizon -->|"Gestione job"| Redis["Coda<br>Redis"]
    Redis -->|"Fetch job"| Worker1["Worker 1"]
    Redis -->|"Fetch job"| Worker2["Worker 2"]
    Redis -->|"Fetch job"| Worker3["Worker 3"]
```

## Installazione

<Warning>
  Horizon usa Redis. Verifica che `QUEUE_CONNECTION` in `config/queue.php` sia `redis`. Al momento non supporta Redis Cluster.
</Warning>

Installazione:

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

Pubblica asset e configurazione:

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

Vengono generati `config/horizon.php` e `app/Providers/HorizonServiceProvider.php`.

## Configurazione

### Struttura di config/horizon.php

`config/horizon.php` gestisce le impostazioni dei worker. Il centro è `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' => [
            'maxProcesses' => 3,
        ],
    ],
],
```

<Info>
  Horizon usa internamente una connessione Redis chiamata `horizon`. Non riutilizzare questo nome in `config/database.php`.
</Info>

### Supervisor

Ogni environment ha uno o più "supervisor". Sono unità di gestione dei worker: puoi avere più supervisor con diverse code, strategie e numero di processi.

### Default

Con `defaults` imposti valori comuni a tutti i supervisor.

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

### Modalità manutenzione

Di default Horizon non elabora job in manutenzione. Con `force` sì.

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

### Tentativi

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

`0` = tentativi illimitati.

### Timeout

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

<Warning>
  `timeout` deve essere qualche secondo minore di `retry_after` in `config/queue.php`. La strategia `auto` può terminare job più lunghi.
</Warning>

### Backoff

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

// Esponenziale
'backoff' => [1, 5, 10],
```

## Strategie di bilanciamento

<AccordionGroup>
  <Accordion title="auto (predefinita)">
    Regola il numero di worker in base al carico.

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

    * `time` — tempo stimato per svuotare la coda
    * `size` — numero di job in coda

    <Info>
      Con `auto` l'ordine delle code non implica priorità. Per priorità stretta usa più supervisor.
    </Info>
  </Accordion>

  <Accordion title="simple">
    Numero di worker fisso, distribuiti tra le code.

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

    5 processi per coda.
  </Accordion>

  <Accordion title="false (nessun bilanciamento)">
    Priorità stretta secondo l'ordine delle code.

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

    `default` sempre prima di `notifications`.
  </Accordion>
</AccordionGroup>

## Autorizzazione della dashboard

La dashboard è su `/horizon`. In locale è accessibile a tutti; in **produzione** limita con una gate.

Modifica `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',
        ]);
    });
}
```

Senza autenticazione (protetto da IP, ad esempio):

```php theme={null}
Gate::define('viewHorizon', function (User $user = null) {
    return true;
});
```

## Avvio di Horizon

### Comandi base

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

# Pausa / ripresa
php artisan horizon:pause
php artisan horizon:continue

# Per supervisor
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1

# Stato
php artisan horizon:status
php artisan horizon:supervisor-status supervisor-1

# Terminazione graceful
php artisan horizon:terminate
```

### Sviluppo locale: auto-restart

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

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

### Supervisor in produzione

Installazione:

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

Configurazione (`/etc/supervisor/conf.d/horizon.conf`):

```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>
  Imposta `stopwaitsecs` più alto del job più lungo.
</Warning>

Avvio:

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

Al deploy, riavvia Horizon:

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

Con Supervisor `autostart=true`/`autorestart=true`, si riavvia da solo.

## Gestione dei job

### Tag

Horizon aggiunge automaticamente tag ai job in base ai modelli Eloquent che ricevono.

```php theme={null}
// Video (id=1) → tag "App\Models\Video:1"
RenderVideo::dispatch(Video::find(1));
```

Tag manuali via `tags()`:

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

Nei listener l'evento viene passato a `tags()`.

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

### Silenziare job

In `config/horizon.php`:

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

'silenced_tags' => [
    'notifications',
],
```

Oppure implementa `Silenced`.

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

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

## Metriche e monitoraggio

Pianifica gli snapshot:

```php theme={null}
use Illuminate\Support\Facades\Schedule;

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

Per cancellare le metriche:

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

## Notifiche dei fallimenti

Notifiche per attese troppo lunghe. In `boot()` di `HorizonServiceProvider`:

```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');
}
```

### Soglie di attesa

In `config/horizon.php`:

```php theme={null}
'waits' => [
    'redis:critical' => 30,
    'redis:default' => 60,
    'redis:batch' => 120,
],
```

`0` disabilita.

## Job falliti

```shell theme={null}
# Elimina uno specifico
php artisan horizon:forget 5

# Elimina tutti i falliti
php artisan horizon:forget --all
```

Svuotare code:

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

## Aggiornamento

Consulta sempre la [Guida all'upgrade](https://github.com/laravel/horizon/blob/master/UPGRADE.md).

## Pagine correlate

<CardGroup cols={2}>
  <Card title="Code e job" href="/it/queues">
    Le basi delle code Laravel: creazione, dispatch, batch e gestione fallimenti.
  </Card>

  <Card title="Redis" href="/it/redis">
    Configurazione e uso di Redis, backend necessario per Horizon.
  </Card>
</CardGroup>


## Related topics

- [Code e job](/it/queues.md)
- [Cache](/it/cache.md)
- [Gestire la compatibilità tra versioni dei pacchetti](/it/advanced/package-versioning.md)
- [Laravel Sentinel — indagine sul middleware di protezione delle rotte](/it/blog/sentinel-introduction.md)
- [Aggiornamenti Laravel di aprile 2026](/it/blog/changelog/202604.md)
