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

> Descubre cómo gestionar y monitorizar visualmente las colas de Redis con Laravel Horizon. Se cubre el panel de control, las estrategias de balanceo, la configuración de Supervisor y las notificaciones.

## Qué es Horizon

[Laravel Horizon](https://github.com/laravel/horizon) es un panel de monitorización específico para las **colas de Redis** de Laravel. Visualiza en tiempo real el rendimiento, el tiempo de ejecución y las incidencias de los jobs, y te permite gestionar la configuración de los workers como código.

<Info>
  Horizon es un paquete que extiende las capacidades básicas de las colas. Familiarízate primero con las [colas y jobs](/es/queues) antes de continuar. Además, necesitas [Redis](/es/redis) como backend obligatorio.
</Info>

```mermaid theme={null}
flowchart LR
    Browser["Navegador"] -->|"/horizon"| Dashboard["Panel de<br>Horizon"]
    Dashboard -->|"Monitor y control"| Horizon["Proceso<br>Horizon"]
    Horizon -->|"Gestión de jobs"| Redis["Cola<br>Redis"]
    Redis -->|"Toma de jobs"| Worker1["Worker 1"]
    Redis -->|"Toma de jobs"| Worker2["Worker 2"]
    Redis -->|"Toma de jobs"| Worker3["Worker 3"]
```

## Instalación

<Warning>
  Horizon utiliza Redis como backend de las colas. Comprueba que `QUEUE_CONNECTION` en `config/queue.php` está fijado a `redis`. Actualmente no admite Redis Cluster.
</Warning>

Instala con Composer.

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

Después publica los assets y el archivo de configuración de Horizon.

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

Este comando genera `config/horizon.php` y `app/Providers/HorizonServiceProvider.php`.

## Configuración

### Estructura de `config/horizon.php`

`config/horizon.php` centraliza toda la configuración de los workers. La sección más importante es `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' => [
            // El resto de valores se hereda de la sección defaults
            'maxProcesses' => 3,
        ],
    ],
],
```

<Info>
  Internamente Horizon utiliza una conexión de Redis llamada `horizon`. No reutilices ese nombre en `config/database.php` para otras conexiones.
</Info>

### Supervisores

Cada entorno puede tener uno o varios «supervisores». Un supervisor es la unidad de gestión de un grupo de workers; puedes ejecutar varios en el mismo entorno con distintas colas, estrategias de balanceo y número de procesos.

### Valores por defecto

La opción `defaults` establece los valores que se aplican a todos los supervisores por defecto.

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

### Modo mantenimiento

Cuando la aplicación está en modo mantenimiento, Horizon no procesa jobs por defecto. Para forzarlo, usa la opción `force`.

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

### Máximo de reintentos

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

Con `tries` a `0` se permiten reintentos ilimitados.

### Timeout de los jobs

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

<Warning>
  El valor de `timeout` debe ser unos segundos inferior a `retry_after` de `config/queue.php`. Además, con la estrategia `auto` los jobs que superen ese tiempo pueden abortarse.
</Warning>

### Backoff (espera antes de reintentar)

Especifica los segundos que hay que esperar antes de reintentar tras una excepción.

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

// Escalonado (backoff exponencial)
'backoff' => [1, 5, 10],
```

## Estrategias de balanceo

Horizon dispone de tres estrategias de balanceo de workers.

<AccordionGroup>
  <Accordion title="auto (por defecto)">
    Ajusta automáticamente el número de workers según la carga de la cola. Con `minProcesses` y `maxProcesses` defines el rango.

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

    * `time`: escala en función del tiempo estimado para vaciar la cola.
    * `size`: escala en función del número de jobs en la cola.

    <Info>
      Con la estrategia `auto` el orden de las colas no implica prioridad. Si necesitas forzar prioridades, utiliza varios supervisores.
    </Info>
  </Accordion>

  <Accordion title="simple">
    Fija el número de workers y los reparte a partes iguales entre las colas indicadas.

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

    En este ejemplo se asignan 5 procesos a `default` y 5 a `notifications`.
  </Accordion>

  <Accordion title="false (sin balanceo)">
    Prioriza estrictamente las colas en el orden en el que se enumeran. Se comporta igual que el sistema de colas por defecto de Laravel, pero escala el número de workers en función del backlog.

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

    Los jobs de la cola `default` se procesarán siempre antes que los de `notifications`.
  </Accordion>
</AccordionGroup>

## Autorización del panel

El panel de Horizon está disponible en la ruta `/horizon`. En entornos locales cualquiera puede acceder por defecto, pero en **producción** debes restringir el acceso mediante un gate.

Edita el método `gate()` en `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',
        ]);
    });
}
```

Si no necesitas autenticación (porque proteges el acceso por IP u otro medio), marca el argumento como opcional.

```php theme={null}
Gate::define('viewHorizon', function (User $user = null) {
    // Cuando el acceso está restringido por IP u otro método
    return true;
});
```

## Arrancar Horizon

### Comandos básicos

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

# Pausar / reanudar
php artisan horizon:pause
php artisan horizon:continue

# Pausar / reanudar un supervisor concreto
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1

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

# Apagado limpio
php artisan horizon:terminate
```

### Desarrollo local: reinicio automático

Para reiniciar Horizon automáticamente cuando cambien los archivos, utiliza `horizon:listen`.

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

# En entornos Docker o Vagrant
php artisan horizon:listen --poll
```

### Ejecución permanente con Supervisor

En producción utiliza Supervisor para mantener Horizon siempre en ejecución.

#### Instalar Supervisor

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

#### Crear el archivo de configuración

Crea `/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>
  Asigna a `stopwaitsecs` un valor mayor que la duración del job más largo. Si es demasiado pequeño, Supervisor abortará los jobs a mitad de ejecución.
</Warning>

#### Arrancar Supervisor

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

#### Al desplegar

Reinicia Horizon en cada despliegue para que se apliquen los cambios.

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

Si Supervisor está configurado con `autostart=true` y `autorestart=true`, Horizon volverá a arrancar automáticamente tras terminar.

## Gestión de jobs

### Etiquetas

Horizon detecta automáticamente los modelos Eloquent que reciben los jobs y les asigna etiquetas.

```php theme={null}
// Un job que recibe el modelo Video (id=1) recibe automáticamente la etiqueta "App\Models\Video:1"
RenderVideo::dispatch(Video::find(1));
```

Para definir etiquetas manualmente, implementa el método `tags()`.

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

En los listeners de eventos, la instancia del evento se pasa como argumento a `tags()`.

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

### Silenciar jobs

Los jobs que no quieras que aparezcan en la lista de «Completed Jobs» pueden silenciarse en `config/horizon.php`.

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

// Silenciar por etiqueta
'silenced_tags' => [
    'notifications',
],
```

También puedes implementar la interfaz `Silenced`.

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

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

## Métricas y monitorización

El panel de métricas de Horizon muestra el rendimiento y los tiempos de ejecución de jobs y colas. Programa un job periódico para capturar snapshots.

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

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

Para eliminar todas las métricas ejecuta:

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

## Notificaciones ante jobs fallidos

Puedes recibir notificaciones cuando las esperas en cola se prolonguen. Configúralo en el método `boot()` de `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');
}
```

### Umbrales de espera

La opción `waits` de `config/horizon.php` define los segundos de espera que disparan la notificación.

```php theme={null}
'waits' => [
    'redis:critical' => 30,  // Notifica si se espera 30 s o más
    'redis:default' => 60,
    'redis:batch' => 120,
],
```

Un valor de `0` deshabilita las notificaciones para esa cola.

## Gestión de jobs fallidos

Los jobs fallidos se eliminan por ID o UUID.

```shell theme={null}
# Elimina un job fallido concreto
php artisan horizon:forget 5

# Elimina todos los jobs fallidos
php artisan horizon:forget --all
```

Para vaciar todos los jobs de una cola:

```shell theme={null}
# Vacía la cola por defecto
php artisan horizon:clear

# Vacía una cola concreta
php artisan horizon:clear --queue=emails
```

## Actualizaciones

Cuando actualices Horizon a una versión mayor, revisa siempre la [guía de actualización](https://github.com/laravel/horizon/blob/master/UPGRADE.md).

## Páginas relacionadas

<CardGroup cols={2}>
  <Card title="Colas y jobs" href="/es/queues">
    Fundamentos de las colas de Laravel: creación y despacho de jobs, procesamiento por lotes y gestión de fallos.
  </Card>

  <Card title="Redis" href="/es/redis">
    Configuración y uso de Redis, backend obligatorio de Horizon.
  </Card>
</CardGroup>


## Related topics

- [Caché](/es/cache.md)
- [Gestión de la compatibilidad de versiones de paquetes](/es/advanced/package-versioning.md)
- [Colas y jobs](/es/queues.md)
- [Laravel Sentinel — Investigación del middleware de protección de rutas](/es/blog/sentinel-introduction.md)
- [Actualización de Laravel — Abril de 2026](/es/blog/changelog/202604.md)
