Laravel Octane держит приложение загруженным в памяти между запросами через Swoole, RoadRunner или FrankenPHP, избегая повторной загрузки контейнера и сервис-провайдеров на каждый запрос. Это не универсальное ускорение, а инструмент для конкретного узкого места — стоимости бутстрапа фреймворка, и он добавляет новый класс ошибок, о котором ниже.
Когда Octane даёт выигрыш, а когда не нужен
Выигрыш заметен там, где бутстрап фреймворка — заметная доля времени запроса: короткие API-эндпоинты с простой бизнес-логикой и высокой частотой запросов. Там, где ответ определяют запросы к базе данных, внешние API или тяжёлый рендеринг шаблонов, доля бутстрапа в общем времени и так мала, и Octane почти ничего не меняет.
Octane требует ядра CPU, которые постоянно заняты резидентными воркерами, в отличие от пула PHP-FPM, который можно держать в режиме dynamic или ondemand. Базовая установка Laravel на VPS с Nginx описана в статье про Laravel на VPS — Octane заменяет в этой схеме обработку HTTP-запросов через FPM-сокет на собственный сервер, который Nginx проксирует отдельно.
Выбор драйвера: Swoole или RoadRunner
Swoole — это PHP-расширение, которое нужно собрать или поставить через PECL; он даёт корутины и встроенный HTTP-сервер. RoadRunner — отдельный бинарник на Go, который обменивается данными с PHP-воркерами через сокет и не требует компиляции расширения, поэтому проще ставится на управляемый VDS. Разница между ними и Swoole-коррутинами в очередях разобрана в статье про Swoole и RoadRunner.
От JIT в OPcache Octane выигрывает меньше, чем ожидают: классы компилируются один раз при старте воркера в обоих режимах — и в FPM, и в Octane, — поэтому базовый OPcache важнее JIT. Настройка разобрана в статье про OPcache и JIT.
Сколько воркеров запускать
Стартовая точка — число воркеров равно числу доступных ядер CPU минус одно ядро, зарезервированное под ОС и другие сервисы: на VDS с 4 ядрами это 3 воркера. В отличие от pm.max_children, здесь нельзя просто увеличивать число процессов под объём RAM — каждый воркер занимает ядро на время обработки запроса, а не ждёт I/O так же легко, как процесс FPM.
- Синхронные HTTP-вызовы без корутин блокируют воркер на всё время ожидания ответа
- Тяжёлая синхронная обработка изображений или регулярных выражений занимает ядро целиком
- Блокирующий драйвер сессий или кэша замедляет каждый запрос в воркере
- Накопление утечек памяти в статических свойствах вынуждает перезапускать воркер чаще
- Лимит подключений к базе данных на каждый воркер ограничивает параллелизм
Таблица: запрос в FPM против воркера Octane
Таблица показывает разницу в жизненном цикле запроса, а не числа производительности — их нужно измерять на своей нагрузке.
| Параметр | PHP-FPM (классический) | Laravel Octane |
|---|---|---|
| Загрузка фреймворка | на каждый запрос | один раз при старте воркера |
| Сброс состояния между запросами | полный, новый процесс | вручную, через сервис-провайдеры |
| Статические свойства и singleton | не накапливаются | могут накапливаться между запросами |
| Перезапуск воркера | после pm.max_requests | после max-requests Octane или octane:reload |
Конфигурация и перезапуск воркеров
Octane запускается одной командой с явным числом воркеров и лимитом запросов на воркер — по аналогии с pm.max_requests это гигиенический перезапуск, который ограничивает накопленную утечку памяти, а не признак поломки.
php artisan octane:start --server=swoole --host=0.0.0.0 --port=8000 --workers=3 --task-workers=2 --max-requests=500Типичные ошибки при переходе на Octane
Самая опасная ошибка — хранить данные конкретного запроса в статическом свойстве класса или в singleton-биндинге контейнера: в FPM это безопасно, потому что процесс живёт один запрос, а в Octane такое значение остаётся в памяти воркера и может попасть в ответ следующему, случайному пользователю.
Вторая типичная ошибка — выставить порт Octane напрямую в интернет. Собственный HTTP-сервер Octane не заменяет Nginx: обратный прокси из статьи про Laravel на VPS остаётся нужен для TLS, ограничения скорости запросов и статики.
Частые вопросы
Нужно ли убирать PHP-FPM, если поставили Octane?
Нет: FPM обычно остаётся для cron-задач, artisan-команд и очередей, которые не проходят через HTTP-цикл Octane — он заменяет только обработку веб-запросов.
Сколько памяти нужно Octane по сравнению с FPM?
Каждый воркер держит загруженный фреймворк в памяти всё время своей жизни, поэтому базовое потребление выше, чем у простаивающего процесса FPM; точное число нужно замерять тем же способом RSS, что и для обычного пула.
Можно ли включить Octane без изменений в коде?
Обычно нет: нужен аудит кода на статическое состояние и сервисы, которые предполагают, что процесс живёт один запрос, а не весь срок жизни воркера.