Laravel Octane
Laravel Octane boots your app once and serves many requests from memory. Falak supervises Octane for you, gives it a private port on every server, and switches the edge to it only after it answers. Deployments restart Octane while Caddy holds incoming requests, so users see a short latency spike instead of errors.
Prerequisites
Section titled “Prerequisites”-
A Laravel site deployed with Falak. See Deploy Laravel.
-
laravel/octaneinstalled in your app:Terminal window composer require laravel/octanephp artisan octane:install --server=frankenphpCommit the result (for FrankenPHP this includes
public/frankenphp-worker.php). -
For Swoole: the
swooleoropenswoolePHP extension on your servers. For RoadRunner: therrbinary andspiral/roadrunner-httpin your app. Falak installs neither.
Choose an Octane server
Section titled “Choose an Octane server”| Octane server | API value | Available on | Default |
|---|---|---|---|
| FrankenPHP (worker mode) | frankenphp |
FrankenPHP sites only | Default on FrankenPHP |
| Swoole | swoole |
PHP-FPM or FrankenPHP sites | Default on PHP-FPM |
| RoadRunner | roadrunner |
PHP-FPM or FrankenPHP sites |
Turn Octane on
Section titled “Turn Octane on”- Open the site’s Settings → Laravel.
- Turn on Octane and pick the server (FrankenPHP is preselected on FrankenPHP sites).
- Save. Falak allocates a port and starts Octane on every server of the site (once the site has a live release).
- The Processes block shows the routing state per server:
starting, thenlisteningonce Octane answered. Only then does the edge proxy to it.
The site card and panel header show an Octane badge.
Through the API:
curl -X PUT https://falak.example.com/api/v1/sites/shop/laravel \ -H "Authorization: Bearer $FALAK_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \ -d '{"octane": true, "octane_server": "frankenphp"}'{"data": {"scheduler": true, "horizon": false, "octane": true, "maintenance": false, "octane_server": "frankenphp", "octane_port": 8412}}How it works
Section titled “How it works”Port allocation. Falak picks the port, you cannot set it. The first candidate is 8000 + crc32(site id) % 1000; if that is taken on any of the site’s servers, it takes the next free one. A port is free when no other site uses it as an app port, Compose host port, Octane port, or Octane auxiliary port (port + 10000, used for FrankenPHP’s --admin-port or RoadRunner’s --rpc-port). The port is kept when you switch Octane off and on again, and re-checked when you add servers.
The program. Falak supervises <slug>.octane:
php8.4 artisan octane:start --server=frankenphp --host=127.0.0.1 --port=8412 --admin-port=18412Routing. Until Octane answers, the site keeps being served the normal way (FrankenPHP php_server or PHP-FPM). A probe waits up to 60 seconds for any HTTP answer on 127.0.0.1:<port>. Once verified, the edge serves existing files under public/ directly (never *.php, dotfiles or directories) and proxies everything else to Octane, retrying the upstream for up to 30 seconds.
Deploys. Octane resolves the current symlink once at start, so a reload would keep serving the old release. After activation, Falak restarts Octane (the program’s environment carries the new FALAK_RELEASE_ID). The old process gets 10 seconds to stop; meanwhile Caddy holds requests until the new process listens. Restart processes in the UI (same release) sends octane:reload instead.
Switching off. The route turns draining: the edge serves the site directly again, and the Octane program stops once no applied edge configuration proxies to it (or after 10 minutes).
Limits
Section titled “Limits”- Falak installs neither Swoole nor RoadRunner. Until they work, the probe keeps the site served directly.
- Octane’s FrankenPHP server binds
:<port>on all interfaces (Octane has no bind option). The server firewall’s default-drop policy blocks it from outside. - Octane under FrankenPHP uses the PHP embedded in the FrankenPHP binary, not the site’s
phpX.YCLI version. - If a verified Octane process crashes later, it is not un-routed automatically: requests get a 502 after the 30-second retry window, and the Process keeps crashing alert fires.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Fix |
|---|---|
State stays starting |
Check the site’s Logs for the octane program. Common causes: laravel/octane not installed, missing public/frankenphp-worker.php, missing Swoole extension. |
State failed |
The probe got no answer in 60 seconds. Fix the error, then redeploy or restart processes. |
| Code changes not visible after deploy | You changed the deploy script to skip $FALAK_RESTART_PROCS. Keep it. |
| Per-request state leaking between requests | Octane keeps your app in memory. Follow the Octane guidelines for singletons and static state. |