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

> Acelera una aplicación Laravel usando FrankenPHP, Swoole o RoadRunner

## ¿Qué es Octane?

[Laravel Octane](https://github.com/laravel/octane) es un paquete que mejora drásticamente el rendimiento de las aplicaciones Laravel usando servidores de aplicaciones de alto rendimiento.

En un PHP-FPM normal, la aplicación se arranca y se termina en cada solicitud. Con Octane, la aplicación se arranca una única vez y se mantiene en memoria, procesando las siguientes solicitudes con gran rapidez.

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Nginx
    participant Octane as Octane<br>(proceso residente)
    participant App as Aplicación<br>Laravel
    Client->>Nginx: Solicitud
    Nginx->>Octane: Proxy
    Octane->>App: Procesa la solicitud (en memoria)
    App->>Nginx: Respuesta
    Nginx->>Client: Respuesta
```

La mayor diferencia respecto a PHP-FPM es que el proceso de arranque de la aplicación (registro de service providers, etc.) no se repite en cada solicitud. Al arrancar una sola vez, las solicitudes se procesan a altísima velocidad.

## Servidores compatibles

Octane admite los siguientes tres servidores.

```mermaid theme={null}
flowchart LR
    A["Elección del servidor"] --> B{"¿Necesitas tareas concurrentes<br>o funciones de Swoole?"}
    B -->|"Sí"| C["Swoole<br>(extensión PECL)"]
    B -->|"No"| D{"¿Necesitas HTTP/3 o<br>compresión Brotli?"}
    D -->|"Sí"| E["FrankenPHP<br>(recomendado)"]
    D -->|"No"| F["RoadRunner<br>(binario en Go)"]
```

| Servidor   | Lenguaje         | Instalación          | Tareas concurrentes | Notas                                           |
| ---------- | ---------------- | -------------------- | ------------------- | ----------------------------------------------- |
| FrankenPHP | Go               | Automática (binario) | —                   | Recomendado. Soporta HTTP/3 y Brotli            |
| RoadRunner | Go               | Automática (binario) | —                   | Sencillo y fácil de configurar                  |
| Swoole     | Extensión de PHP | Manual con PECL      | ✅                   | Ofrece tareas concurrentes y la caché de Octane |

<Info>
  En Laravel Cloud se recomienda operar Octane con FrankenPHP y ofrece soporte totalmente gestionado.
</Info>

## Instalación y configuración

### Instalación del paquete

```bash theme={null}
composer require laravel/octane
```

### Configuración inicial de Octane

```bash theme={null}
php artisan octane:install
```

Al ejecutarlo se muestra un prompt para elegir el servidor. Al seleccionarlo se genera `config/octane.php`.

### FrankenPHP

Al elegir FrankenPHP, Octane descarga automáticamente el binario. No hacen falta pasos adicionales.

### RoadRunner

Al elegir RoadRunner, Octane descarga automáticamente el binario.

### Swoole

Swoole se instala como extensión de PHP con PECL.

```bash theme={null}
pecl install swoole
```

Para usar Open Swoole, ejecuta:

```bash theme={null}
pecl install openswoole
```

## Cómo arrancar

### Arrancar el servidor

```bash theme={null}
php artisan octane:start
```

Por defecto arranca en el puerto `8000`. Accede en `http://localhost:8000`.

### Indicar el servidor

```bash theme={null}
php artisan octane:start --server=frankenphp
php artisan octane:start --server=roadrunner
php artisan octane:start --server=swoole
```

### Indicar el número de workers

```bash theme={null}
php artisan octane:start --workers=4
```

Para especificar también los task workers en Swoole:

```bash theme={null}
php artisan octane:start --workers=4 --task-workers=6
```

### Observación de cambios en archivos

Durante el desarrollo, los cambios en los archivos no se reflejan sin reiniciar el servidor. Con `--watch` se reinicia automáticamente.

```bash theme={null}
php artisan octane:start --watch
```

<Warning>
  Para usar `--watch` necesitas [Node.js](https://nodejs.org) y Chokidar.

  ```bash theme={null}
  npm install --save-dev chokidar
  ```
</Warning>

### Otros comandos de gestión

```bash theme={null}
# Recargar workers (ejecutar tras el despliegue)
php artisan octane:reload

# Parar el servidor
php artisan octane:stop

# Comprobar el estado del servidor
php artisan octane:status
```

## Consideraciones sobre inyección de dependencias

En Octane la aplicación se mantiene en memoria, por lo que **`register` y `boot` de los service providers solo se ejecutan una vez, al arrancar el servidor**. La misma instancia de la aplicación se reutiliza entre solicitudes, así que hay que tener cuidado al inyectar el contenedor o la solicitud en el constructor de un objeto.

```mermaid theme={null}
flowchart LR
    A["Arranque del servidor<br>(una sola vez)"] --> B["ServiceProvider<br>register / boot"]
    B --> C["Instancia de la aplicación<br>(en memoria)"]
    C --> D["Solicitud 1"]
    C --> E["Solicitud 2"]
    C --> F["Solicitud 3..."]
```

### Inyección del contenedor

Si inyectas el contenedor directamente en el constructor de un singleton, se reutiliza un contenedor antiguo.

```php theme={null}
// ❌ Problemático: se reutiliza un contenedor antiguo
$this->app->singleton(Service::class, function (Application $app) {
    return new Service($app);
});

// ✅ Seguro: obtén siempre el contenedor más reciente con un closure
$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance());
});
```

Los helpers globales `app()` y `Container::getInstance()` siempre devuelven el contenedor más reciente, así que son seguros.

### Inyección de la solicitud

```php theme={null}
// ❌ Problemático: se reutiliza una solicitud antigua
$this->app->singleton(Service::class, function (Application $app) {
    return new Service($app['request']);
});

// ✅ Seguro: obtén siempre la solicitud más reciente con un closure
$this->app->singleton(Service::class, function (Application $app) {
    return new Service(fn () => $app['request']);
});

// ✅ Más recomendado: pasa solo el valor necesario al método
$service->method($request->input('name'));
```

<Info>
  Tipar `Illuminate\Http\Request` en los métodos del controlador o en closures de ruta es seguro. El helper global `request()` también devuelve siempre la solicitud actual.
</Info>

### Inyección del repositorio de configuración

```php theme={null}
// ❌ Problemático: si los valores cambian, se usa un repositorio antiguo
$this->app->singleton(Service::class, function (Application $app) {
    return new Service($app->make('config'));
});

// ✅ Seguro
$this->app->singleton(Service::class, function () {
    return new Service(fn () => Container::getInstance()->make('config'));
});
```

El helper global `config()` siempre devuelve el repositorio de configuración más reciente, así que es seguro.

## Mitigación de fugas de memoria

Como Octane mantiene la aplicación en memoria, acumular datos en propiedades estáticas provoca fugas.

```php theme={null}
// ❌ Ejemplo de fuga: $data crece con cada solicitud
class Service
{
    public static array $data = [];
}

public function index(Request $request): array
{
    Service::$data[] = Str::random(10);
    return [];
}
```

### Reciclar workers con max-requests

Al reiniciar automáticamente el worker tras un cierto número de solicitudes se atenúan las fugas de memoria. El valor por defecto es 500 solicitudes.

```bash theme={null}
php artisan octane:start --max-requests=250
```

### Configuración del tiempo máximo de ejecución

Puedes definir el tiempo máximo de una solicitud en `config/octane.php`. Por defecto son 30 segundos.

```php theme={null}
'max_execution_time' => 30,
```

<Warning>
  Si cambias `max_execution_time`, reinicia el servidor Octane.
</Warning>

## Tareas concurrentes (solo Swoole)

Con Swoole puedes ejecutar varias operaciones en paralelo con `Octane::concurrently()`.

```php theme={null}
use App\Models\User;
use App\Models\Server;
use Laravel\Octane\Facades\Octane;

[$users, $servers] = Octane::concurrently([
    fn () => User::all(),
    fn () => Server::all(),
]);
```

Las tareas concurrentes se ejecutan como "task workers" de Swoole en procesos separados. Indica el número con `--task-workers`.

```bash theme={null}
php artisan octane:start --workers=4 --task-workers=6
```

<Warning>
  A `concurrently` se le pueden pasar como máximo 1024 tareas (límite de Swoole).
</Warning>

## Tick e Interval (solo Swoole)

En Swoole puedes registrar tareas que se ejecutan a intervalos regulares. Se registran en el método `boot` de un service provider.

```php theme={null}
use Laravel\Octane\Facades\Octane;

// Se ejecuta cada 10 segundos
Octane::tick('delayed-ticker', fn () => ray('Ticking...'))
    ->seconds(10);

// También se ejecuta inmediatamente al arrancar el servidor
Octane::tick('immediate-ticker', fn () => ray('Ticking...'))
    ->seconds(10)
    ->immediate();
```

## Caché de Octane (solo Swoole)

Caché en memoria ultrarrápida basada en las [tablas de Swoole](https://www.swoole.co.uk/docs/modules/swoole-table). Soporta hasta 2 millones de lecturas/escrituras por segundo.

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

Cache::store('octane')->put('framework', 'Laravel', 30);
```

### Caché con intervalo

Caché que se actualiza automáticamente cada cierto tiempo.

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

Cache::store('octane')->interval('random', function () {
    return Str::random(10);
}, seconds: 5);
```

<Warning>
  Los datos de la caché de Octane se pierden al reiniciar el servidor.
</Warning>

## Tablas de Swoole (solo Swoole)

Puedes definir tablas en memoria accesibles desde todos los workers. Se configuran en `tables` de `config/octane.php`.

```php theme={null}
'tables' => [
    'example:1000' => [
        'name' => 'string:1000',
        'votes' => 'int',
    ],
],
```

Accede a la tabla con `Octane::table()`.

```php theme={null}
use Laravel\Octane\Facades\Octane;

Octane::table('example')->set('uuid', [
    'name' => 'Nuno Maduro',
    'votes' => 1000,
]);

$row = Octane::table('example')->get('uuid');
```

<Warning>
  Los únicos tipos de columna soportados por las tablas de Swoole son `string`, `int` y `float`. Los datos se pierden al reiniciar el servidor.
</Warning>

## Operación en producción

### Configuración Nginx + Octane

En producción es habitual ejecutar Octane detrás de Nginx. Nginx sirve los archivos estáticos y termina SSL, mientras que las solicitudes dinámicas se pasan por proxy a Octane.

```nginx theme={null}
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name example.com;
    root /home/forge/example.com/public;

    location /index.php {
        try_files /not_exists @octane;
    }

    location / {
        try_files $uri $uri/ @octane;
    }

    location @octane {
        set $suffix "";

        if ($uri = /index.php) {
            set $suffix ?$query_string;
        }

        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_pass http://127.0.0.1:8000$suffix;
    }
}
```

### Ejecución permanente con Supervisor

En producción, usa Supervisor para mantener Octane siempre activo.

```ini theme={null}
[program:octane]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/example.com/artisan octane:start --server=frankenphp --host=127.0.0.1 --port=8000
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/example.com/storage/logs/octane.log
stopwaitsecs=3600
```

### Habilitar HTTPS

Para generar enlaces HTTPS a través de Octane, configura en `.env`:

```ini theme={null}
OCTANE_HTTPS=true
```

### Integración con Laravel Cloud

[Laravel Cloud](https://cloud.laravel.com) ofrece soporte totalmente gestionado para Octane con FrankenPHP. No necesitas configurar Nginx ni Supervisor: puedes activarlo en solo dos pasos.

<Steps>
  <Step title="Instalación del paquete">
    Instala Octane. Ejecutar `octane:install` es opcional.

    ```bash theme={null}
    composer require laravel/octane
    ```
  </Step>

  <Step title="Activar Octane en Laravel Cloud">
    En la configuración del cluster de cómputo del entorno, activa **"Use Octane as runtime"** y guarda/despliega. Laravel Cloud construirá y arrancará automáticamente la aplicación con FrankenPHP + Octane.
  </Step>
</Steps>

Consulta la [documentación de Laravel Cloud](https://cloud.laravel.com/docs/compute#laravel-octane) para más detalles.

### Recargar workers tras el despliegue

Tras un despliegue, recarga los workers para cargar el nuevo código en memoria.

```bash theme={null}
php artisan octane:reload
```


## Related topics

- [Laravel Cloud — Todo sobre el PaaS específico para Laravel](/es/blog/laravel-cloud.md)
- [Crear un servidor MCP con Laravel](/es/advanced/mcp-server.md)
- [Despliegue](/es/deployment.md)
- [Laravel Telescope](/es/telescope.md)
- [Laravel Bluesky](/es/packages/laravel-bluesky/index.md)
