Laravel Octane em 2026: Swoole, RoadRunner e Otimizacao de Performance

Guia completo sobre Laravel Octane 2.19: escolha entre FrankenPHP, Swoole e RoadRunner, prevencao de vazamentos de memoria e configuracao para producao.

Performance do Laravel Octane com Swoole, RoadRunner e FrankenPHP em 2026

Laravel Octane transforma a performance de aplicacoes PHP ao manter o framework inicializado em memoria entre requisicoes. A versao 2.19 (agosto de 2026) suporta tres servidores prontos para producao: FrankenPHP, Swoole e RoadRunner. Cada um atende a diferentes requisitos operacionais, e escolher o errado custa em performance ou estabilidade.

Referencia Rapida de Selecao de Servidor

FrankenPHP: configuracao mais simples, HTTP/3 nativo, binario unico. RoadRunner: binario Go testado em batalha, sem extensoes PHP necessarias. Swoole: throughput maximo com concorrencia via coroutines, requer gerenciamento de extensao PECL.

Como o Octane Elimina a Sobrecarga de Bootstrap

O PHP-FPM tradicional cria um novo processo por requisicao. O Laravel inicializa seu container de servicos, carrega configuracoes, registra providers e resolve middlewares em cada chamada HTTP. O Octane inverte esse modelo: a aplicacao inicializa uma vez por worker, e entao a mesma instancia processa milhares de requisicoes sequencialmente.

O ganho de performance vem da eliminacao de trabalho repetitivo. Uma aplicacao Laravel 12 tipica gasta entre 15 e 40ms no bootstrap antes de executar a logica de negocio. Com o Octane, esse custo cai para zero apos a primeira requisicao. Benchmarks em hardware identico mostram melhorias de throughput de 2x a 4x para endpoints de API, com a diferenca aumentando conforme a complexidade da aplicacao cresce.

config/octane.phpphp
return [
    'server' => env('OCTANE_SERVER', 'frankenphp'),
    
    // Workers handle HTTP requests
    'workers' => env('OCTANE_WORKERS', 8),
    
    // Gracefully restart workers after N requests to prevent memory bloat
    'max_requests' => env('OCTANE_MAX_REQUESTS', 500),
    
    // Task workers for Swoole concurrent operations
    'task_workers' => env('OCTANE_TASK_WORKERS', 6),
    
    // Maximum execution time per request in seconds
    'max_execution_time' => 30,
];

A configuracao max_requests atua como uma valvula de seguranca. Mesmo codigo bem escrito pode acumular memoria ao longo de centenas de requisicoes. Definir isso como 500 forca os workers a reiniciar antes que a pressao de memoria se torne problematica.

FrankenPHP: O Padrao de 2026 para Novos Projetos

FrankenPHP e distribuido como um binario unico construido sobre Caddy e PHP. Ele gerencia certificados HTTPS automaticamente atraves do Let's Encrypt, suporta HTTP/3 nativamente e nao requer instalacao de extensoes PHP. O instalador do Laravel e os exemplos de producao agora usam FrankenPHP por padrao.

bash
# Install Octane with FrankenPHP
composer require laravel/octane
php artisan octane:install --server=frankenphp

# Start the server
php artisan octane:start --server=frankenphp --host=0.0.0.0 --port=8000

Para deploys em containers, o FrankenPHP fornece imagens Docker oficiais:

dockerfile
# Dockerfile
FROM dunglas/frankenphp

RUN install-php-extensions \
    pcntl \
    pdo_pgsql \
    redis

COPY . /app

ENTRYPOINT ["php", "artisan", "octane:frankenphp"]

A configuracao do Docker Compose para desenvolvimento habilita HTTPS e HTTP/3:

yaml
# compose.yaml
services:
  frankenphp:
    build:
      context: .
    entrypoint: php artisan octane:frankenphp --workers=1 --max-requests=1
    ports:
      - "443:443"
      - "443:443/udp"
    volumes:
      - .:/app

O FrankenPHP gerencia reinicializacoes de workers de forma elegante e se integra diretamente com o sistema de middlewares do Caddy para cenarios de roteamento avancados.

RoadRunner: Estabilidade em Go Sem Dependencias de Extensoes

RoadRunner compila para um binario Go que gerencia processos workers PHP. Ele se comunica com o PHP atraves de um protocolo binario, mantendo o gerenciamento de workers e o tratamento HTTP em Go enquanto executa o codigo da aplicacao em PHP. Essa arquitetura fornece isolamento de processos: um worker PHP que falha nao afeta o pai Go nem os workers irmaos.

bash
# Install Octane with RoadRunner
composer require laravel/octane spiral/roadrunner-cli spiral/roadrunner-http

php artisan octane:install --server=roadrunner

# Download the RoadRunner binary
./vendor/bin/rr get-binary

# Start the server
php artisan octane:start --server=roadrunner --host=0.0.0.0 --port=8000

A configuracao do RoadRunner fica em .rr.yaml na raiz do projeto:

yaml
# .rr.yaml
version: "3"

server:
  command: "php artisan octane:start --server=roadrunner --host=0.0.0.0 --port=8000"
  relay: pipes

http:
  address: 0.0.0.0:8000
  middleware: ["headers", "gzip"]
  pool:
    num_workers: 8
    max_jobs: 500
    supervisor:
      max_worker_memory: 128

A configuracao max_worker_memory (em MB) termina workers que excedem os limites de memoria, fornecendo uma rede de seguranca adicional alem do max_requests. Para equipes com pipelines de CI estabelecidos e infraestrutura PHP-FPM existente, o RoadRunner oferece o caminho de migracao mais suave.

Swoole: Throughput Maximo com Concorrencia via Coroutines

Swoole opera como uma extensao PHP que substitui o ciclo de vida padrao de requisicoes por um runtime orientado a eventos capaz de lidar com coroutines. Ele fornece recursos indisponiveis em outros servidores: execucao concorrente de tarefas, ticks e intervalos, e um cache em memoria com throughput de 2 milhoes de operacoes por segundo.

bash
# Install Swoole via PECL
pecl install swoole

# Add to php.ini
echo "extension=swoole.so" >> $(php --ini | grep "Loaded Configuration" | cut -d: -f2 | xargs)/php.ini

# Install Octane with Swoole
composer require laravel/octane
php artisan octane:install --server=swoole

# Start with task workers for concurrent operations
php artisan octane:start --server=swoole --workers=8 --task-workers=6

A execucao concorrente de tarefas do Swoole gerencia operacoes de I/O paralelas dentro de uma unica requisicao:

app/Http/Controllers/DashboardController.phpphp
use App\Models\User;
use App\Models\Order;
use App\Models\Analytics;
use Laravel\Octane\Facades\Octane;

class DashboardController extends Controller
{
    public function index()
    {
        // Execute three queries concurrently instead of sequentially
        [$users, $orders, $analytics] = Octane::concurrently([
            fn () => User::active()->count(),
            fn () => Order::today()->sum('total'),
            fn () => Analytics::hourly()->get(),
        ]);

        return view('dashboard', compact('users', 'orders', 'analytics'));
    }
}

Sem Octane::concurrently(), essas tres consultas executam sequencialmente: 50ms + 30ms + 40ms = 120ms no total. Com execucao concorrente, o tempo total e igual a consulta mais lenta: 50ms. A flag --task-workers controla quantas operacoes concorrentes podem executar simultaneamente em todos os workers de requisicoes.

Recursos Exclusivos do Swoole

Tarefas concorrentes, ticks, intervalos, cache do Octane e tabelas Swoole requerem a extensao Swoole. FrankenPHP e RoadRunner nao suportam esses recursos. Deve-se avaliar se a aplicacao precisa deles antes de se comprometer com a complexidade operacional do Swoole.

Prevencao de Vazamentos de Memoria: Escrevendo Codigo Stateless

A performance do Octane vem do estado persistente, o que cria o principal desafio: codigo que funcionava bem sob PHP-FPM pode vazar memoria catastroficamente sob o Octane. A instancia da aplicacao sobrevive entre requisicoes, entao propriedades estaticas, singletons e estado global se acumulam.

Tres padroes causam a maioria dos vazamentos de memoria:

Arrays estaticos que crescem sem limite:

php
// WRONG: Memory leak - array grows with every request
class MetricsCollector
{
    public static array $data = [];

    public static function record(string $metric): void
    {
        self::$data[] = $metric; // Never cleared between requests
    }
}

// CORRECT: Use request-scoped storage or external systems
class MetricsCollector
{
    public function record(string $metric): void
    {
        Redis::lpush('metrics', $metric); // External storage
    }
}

Singletons armazenando dados especificos da requisicao:

php
// WRONG: First request's user leaks into subsequent requests
$this->app->singleton(UserContext::class, function ($app) {
    return new UserContext($app['request']->user());
});

// CORRECT: Use closures for deferred resolution
$this->app->singleton(UserContext::class, function ($app) {
    return new UserContext(fn () => $app['request']->user());
});

Injecao do container e da requisicao em construtores:

php
// WRONG: Captures stale container/request
class PaymentService
{
    public function __construct(
        private Application $app,
        private Request $request
    ) {}
}

// CORRECT: Inject via method parameters or use helpers
class PaymentService
{
    public function processPayment(Request $request): void
    {
        $user = $request->user();
        $config = config('services.stripe.key'); // Global helper, always fresh
    }
}

Os helpers globais app(), request() e config() sempre retornam valores atuais. Usa-los ao inves de injecao por construtor evita a maioria dos vazamentos relacionados a singletons.

Padroes de Deploy em Producao

Servidores Octane precisam de supervisao de processos para reiniciar em caso de falhas. O Supervisor gerencia isso de forma confiavel:

ini
; /etc/supervisor/conf.d/octane.conf
[program:octane]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app/artisan octane:start --server=frankenphp --host=127.0.0.1 --port=8000
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/app/storage/logs/octane.log
stopwaitsecs=3600

Para deploys, os workers do Octane devem ser recarregados para pegar o novo codigo. O comando octane:reload gerencia isso de forma elegante, esperando que as requisicoes em andamento sejam concluidas antes de reciclar os workers:

bash
# In deployment script (after git pull, composer install, etc.)
php artisan octane:reload

O Nginx fica na frente do Octane para servir assets estaticos e terminar SSL:

nginx
# /etc/nginx/sites-available/app.conf
upstream octane {
    server 127.0.0.1:8000;
    keepalive 32;
}

server {
    listen 443 ssl http2;
    server_name example.com;
    root /var/www/app/public;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

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

    location @octane {
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection "";
        proxy_pass http://octane;
    }
}

A diretiva keepalive mantem conexoes persistentes entre Nginx e Octane, reduzindo a sobrecarga de handshakes TCP para requisicoes proxificadas.

Pronto para mandar bem nas entrevistas de Laravel?

Pratique com nossos simuladores interativos, flashcards e testes tecnicos.

Arvore de Decisao para Selecao de Servidor

Escolher entre FrankenPHP, RoadRunner e Swoole depende das restricoes operacionais e requisitos da aplicacao:

RequisitoServidor Recomendado
Configuracao mais simples, deploy em containersFrankenPHP
Suporte HTTP/3 nativoFrankenPHP
Sem dependencias de extensoes PHPFrankenPHP ou RoadRunner
Maximo isolamento de processosRoadRunner
Infraestrutura PHP-FPM estabelecidaRoadRunner
I/O concorrente dentro de requisicoesSwoole
Cache em memoria (2M ops/seg)Swoole
Ticks, intervalos, tarefas em backgroundSwoole
Tabelas Swoole para estado compartilhadoSwoole

Para equipes iniciando novos projetos em 2026, o FrankenPHP fornece o melhor equilibrio entre simplicidade e capacidade. A migracao de aplicacoes existentes funciona melhor com RoadRunner devido ao seu isolamento de processos e modelo de deploy familiar. O Swoole e adequado para APIs de alto throughput que se beneficiam da concorrencia via coroutines e requerem recursos especificos do Swoole.

Perguntas de Entrevista sobre Laravel Octane

Entrevistas tecnicas cobrem cada vez mais o Octane conforme aplicacoes Laravel de alto trafego o adotam. Perguntas comuns e o que os entrevistadores buscam:

"Como o Octane alcanca seus ganhos de performance?"

A resposta esperada: O Octane inicializa o Laravel uma vez por worker e reutiliza essa instancia entre requisicoes, eliminando o custo de bootstrap de 15-40ms em cada requisicao. Os candidatos devem mencionar que os metodos register e boot dos service providers executam uma vez por worker, nao por requisicao.

"O que causa vazamentos de memoria em aplicacoes Octane?"

Respostas solidas identificam tres fontes: arrays estaticos que acumulam dados, singletons capturando estado especifico da requisicao, e injecao por construtor do container ou objetos de requisicao. Os candidatos devem explicar que a correcao envolve usar closures para resolucao adiada ou passar dados atraves de parametros de metodo.

"Quando voce escolheria Swoole ao inves de RoadRunner?"

As vantagens do Swoole sao concorrencia via coroutines atraves de Octane::concurrently(), o cache Octane de alta velocidade, e recursos como ticks e intervalos. A contrapartida e a complexidade operacional: o Swoole requer gerenciar uma extensao PECL, enquanto o RoadRunner vem como um binario Go. Para aplicacoes CRUD sem necessidades de I/O concorrente, o RoadRunner e mais simples de operar. Para mais preparacao de entrevistas Laravel, veja Perguntas de Entrevista para Desenvolvedores PHP Laravel 2026.

"Como voce gerencia deploys com Octane?"

A sequencia de deploy: parar de aceitar novas conexoes, esperar que requisicoes em andamento sejam concluidas, recarregar workers com o novo codigo. O comando php artisan octane:reload gerencia isso. Os candidatos devem mencionar Supervisor ou systemd para supervisao de processos e Nginx ou Caddy como reverse proxy.

Monitoramento e Profiling de Aplicacoes Octane

O monitoramento de memoria se torna critico sob o Octane. Os workers persistem, entao o crescimento de memoria indica vazamentos ao inves de sobrecarga normal de requisicao. Laravel Pulse e Telescope funcionam com o Octane e fornecem profiling a nivel de requisicao.

app/Providers/AppServiceProvider.phpphp
use Laravel\Octane\Events\RequestReceived;
use Laravel\Octane\Events\RequestTerminated;

public function boot(): void
{
    Event::listen(RequestReceived::class, function ($event) {
        $event->sandbox->instance('request.memory.start', memory_get_usage());
    });

    Event::listen(RequestTerminated::class, function ($event) {
        $start = $event->sandbox->make('request.memory.start');
        $delta = memory_get_usage() - $start;
        
        if ($delta > 1024 * 1024) { // More than 1MB growth
            Log::warning('High memory delta', [
                'path' => $event->request->path(),
                'delta_mb' => round($delta / 1024 / 1024, 2),
            ]);
        }
    });
}

Esse listener de eventos registra requisicoes que aumentam a memoria em mais de 1MB, ajudando a identificar endpoints que precisam de otimizacao. Para monitoramento em producao, ferramentas APM externas como Datadog ou New Relic fornecem visibilidade a nivel de worker.

Integracao do Octane com Queues e Horizon

O Octane gerencia requisicoes HTTP; o Laravel Horizon gerencia workers de filas. Os dois operam independentemente e se complementam. O processamento pesado pertence a jobs na fila, mantendo os workers do Octane responsivos.

app/Http/Controllers/ReportController.phpphp
use App\Jobs\GenerateReport;

class ReportController extends Controller
{
    public function generate(Request $request)
    {
        // Dispatch to queue instead of blocking the Octane worker
        GenerateReport::dispatch($request->user(), $request->input('parameters'));

        return response()->json(['status' => 'processing']);
    }
}

Para padroes relacionados sobre processamento em background, veja Laravel Queues and Jobs: Asynchronous Architecture e Laravel Middleware Deep Dive.

Pontos-Chave sobre Laravel Octane em 2026

  • O Octane 2.19 suporta tres servidores: FrankenPHP (o mais simples), RoadRunner (o mais estavel) e Swoole (o com mais recursos)
  • Os ganhos de performance vem da eliminacao do bootstrap por requisicao; espera-se melhoria de throughput de 2x a 4x
  • Vazamentos de memoria ocorrem porque o estado do worker persiste; deve-se evitar arrays estaticos, requisicoes injetadas por construtor e singletons com dados de requisicao
  • Use --max-requests=500 para forcar a reciclagem de workers antes que a pressao de memoria se acumule
  • Recursos exclusivos do Swoole incluem Octane::concurrently(), ticks, intervalos e o cache do Octane
  • Faca deploy atras de Nginx ou Caddy com Supervisor para gerenciamento de processos
  • Profile o crescimento de memoria por requisicao; deltas acima de 1MB indicam possiveis vazamentos
  • Enfileire trabalho pesado atraves do Horizon; mantenha os workers do Octane para respostas HTTP rapidas

Comece a praticar!

Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.

Desafio do dia

Você saberia encontrar o bug em Laravel?

Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Anthony Fillion-Maillet

Escrito por

Anthony Fillion-Maillet

Fundador da SharpSkill

Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.

Atualizado em 11 de setembro de 2026

Tags

#laravel
#octane
#swoole
#roadrunner
#frankenphp
#performance
#php

Compartilhar

Artigos relacionados