If you run a Laravel application in production, there’s a good chance it’s running on PHP-FPM right now. That’s the default, and for a lot of apps it’s the right call. But at some point you start wondering: is my app slow because of my code, or because PHP is booting the entire framework on every single request? That’s the question Laravel Octane vs PHP-FPM tries to answer, and this guide will help you make the call with real numbers instead of vibes.
Laravel Octane isn’t a different Laravel. It’s a package that boots your application once, keeps it in memory, and serves requests using high-performance application servers — Swoole, RoadRunner, or FrankenPHP — instead of the traditional per-request PHP-FPM model. The performance gains are real, but so is the operational complexity. Let’s break down exactly when the switch pays off and when it doesn’t.
How PHP-FPM and Laravel Octane Actually Differ
To decide, you need to understand what each one is doing under the hood.
The PHP-FPM model: boot everything, every time
With PHP-FPM, every incoming request starts a fresh PHP process (or reuses one from a pool, but either way the application state starts from zero). Laravel then bootstraps: it loads configuration, registers service providers, builds the container, and only then handles your request. On a typical Laravel app, that bootstrap costs somewhere in the tens of milliseconds — before your code even runs.
For a simple app, that cost is a rounding error. For a complex app under load, it’s the dominant cost of every request. PHP-FPM’s strength is isolation: because nothing persists between requests, memory leaks are nearly impossible and stale state can’t leak from one user to another.
The Octane model: boot once, serve many
Laravel Octane flips the model. As the official Laravel Octane documentation puts it: Octane boots your application once, keeps it in memory, and then feeds it requests at supersonic speeds. The framework bootstrap cost is paid exactly once per worker process, and every request after that goes straight to your code.
Octane supports three application servers:
- Swoole / Open Swoole — a PHP extension. Best raw throughput, coroutines, task workers, WebSockets.
- RoadRunner — a Go-based server binary. No PHP extension needed, easier deployment, strong performance.
- FrankenPHP — built on the Caddy web server. Automatic HTTPS, HTTP/2 and HTTP/3 support, and the binary is downloaded automatically during install.
Getting started is genuinely simple:
composer require laravel/octane
php artisan octane:install
php artisan octane:start --server=frankenphp
Laravel Octane requires PHP 8.1+. But getting it running is not the same as getting it running safely — more on that below.
Real Benchmarks: What the Numbers Actually Say
Forget the hello-world benchmarks from announcement posts. The most useful public numbers come from a Deploynix benchmark published in April 2026, run with wrk (100 concurrent connections, 30 seconds) on a Hetzner CX32 server (4 vCPU, 8 GB RAM, PHP 8.4) against a representative Laravel app — Eloquent queries, cache reads, Blade rendering. Not a bare route.
Throughput (requests per second)
| Configuration | RPS | vs PHP-FPM |
|---|---|---|
| PHP-FPM (10 workers) | 850 | 1.0x baseline |
| Octane + FrankenPHP (4 workers) | 2,100 | 2.5x |
| Octane + RoadRunner (4 workers) | 2,350 | 2.8x |
| Octane + Swoole (4 workers) | 2,600 | 3.1x |
So Octane delivers roughly 2.5–3.1x the throughput, and note the worker counts: four Octane workers outperform ten PHP-FPM workers. The gain comes almost entirely from eliminating the framework bootstrap on each request.
Latency (lower is better)
| Configuration | P50 | P95 | P99 |
|---|---|---|---|
| PHP-FPM | 45ms | 120ms | 250ms |
| Octane + FrankenPHP | 18ms | 48ms | 95ms |
| Octane + RoadRunner | 16ms | 42ms | 88ms |
| Octane + Swoole | 14ms | 38ms | 78ms |
Median latency drops by roughly 60–70% across all three drivers. For time-to-first-byte on cached pages, the difference is even more dramatic: 25ms under PHP-FPM versus 3–5ms under Octane, because the framework is already booted and cached data is already sitting in the worker’s memory.
Memory: the real trade-off
| Configuration | Per-worker memory |
|---|---|
| PHP-FPM | 30–50 MB |
| Octane + FrankenPHP | 60–90 MB |
| Octane + RoadRunner | 55–85 MB |
| Octane + Swoole | 65–100 MB |
Octane workers hold the entire bootstrapped application in memory, so each worker costs roughly double the memory of a PHP-FPM worker. But because you need far fewer workers for the same throughput, total memory usage ends up comparable.
When You Should Switch to Laravel Octane
Switch when the numbers say so, not when the hype says so. Octane earns its keep in these situations:
1. Your requests are CPU-bound, not I/O-bound
This is the single most important factor, and it’s the one people get wrong most often. If your request spends most of its time waiting on the database, an external API, or an outbound HTTP call, Octane won’t move your numbers much — the bootstrap it removes is a small fraction of an I/O-bound request.
Octane shines on CPU-bound, framework-heavy requests served at high rates: an API doing real work in PHP, a dashboard rendering complex views, anything where the time is spent in your code rather than waiting on someone else’s. There, the skipped bootstraps compound into something you can measure.
2. Latency is a competitive advantage
If you’re building a SaaS where snappy responses differentiate you, a 60–70% median latency reduction is meaningful. APIs with strict SLAs, real-time dashboards, and high-frequency polling endpoints all benefit disproportionately.
3. You want to cut server costs at scale
Handling 2.5–3x the throughput per worker means fewer instances for the same traffic. On a single small VPS this doesn’t matter; on a fleet of app servers it absolutely does.
4. You need Octane-only features
With the Swoole driver you get concurrent tasks, an in-memory cache driver capable of millions of operations per second, tick/interval scheduling, and WebSocket support — things PHP-FPM simply cannot do:
use Laravel\Octane\Facades\Octane;
use App\Models\User;
use App\Models\Server;
[$users, $servers] = Octane::concurrently([
fn () => User::all(),
fn () => Server::all(),
]);
When You Should Stay on PHP-FPM
Sometimes the best performance decision is to change nothing. Mattias Geniar documented moving his entire fleet back to PHP-FPM after running Octane on FrankenPHP, and his conclusion is worth quoting: “If your requests are dominated by I/O, waiting on a database, an API, an outbound call, don’t expect Octane to move your numbers much.” Stay on PHP-FPM if:
1. You’re on shared hosting or a managed platform
Octane needs a long-running server process you control. Shared hosting won’t allow it, and some managed platforms (Laravel Forge gives you PHP-FPM out of the box) don’t manage the Octane stack for you — you’d be hand-rolling systemd units, pinned binaries, and proxy config. That’s a parallel serving stack and a new set of failure modes.
2. Your traffic is low to moderate
If your app serves a few hundred requests per minute, the performance difference is imperceptible. A 45ms response versus a 15ms response doesn’t change the user experience when network round trips and frontend rendering dominate perceived latency.
3. Your codebase isn’t “Octane-safe”
This is the hidden cost. Because workers persist between requests, anything stored in static properties, singletons, or the container can leak from one request into the next — one user’s data showing up in another user’s response. Large legacy codebases and older packages are the worst offenders here. Auditing for request isolation is a significant undertaking, and getting it wrong produces the nastiest kind of bug: intermittent, hard to reproduce, and data-sensitive.
4. Simplicity is your priority
PHP-FPM is battle-hardened. There’s no memory-leak risk, no state isolation concerns, and decades of troubleshooting knowledge. If your team isn’t comfortable with the concepts of long-running workers and memory management, Octane’s performance won’t be worth the operational drag.
How to Try Octane Safely (Without Betting the Farm)
You don’t have to commit. The smart path is a staged evaluation:
- Benchmark your actual app first. Clone production traffic or replay a realistic workload against both setups in staging. Use
wrkor ApacheBench against a representative route — not a hello-world endpoint. Measure your own workload, on your real traffic, before and after. - Audit for static state. Search your codebase and your key packages for static properties, singletons holding request data, and anything cached in memory that should be per-request. Octane ships listeners that flush common Laravel state between requests, and you can add your own in
config/octane.php. - Set a max-requests ceiling. Configure workers to restart after a few hundred requests — this bounds the blast radius of slow memory leaks while you find them:
php artisan octane:start --server=frankenphp --workers=4 --max-requests=500
- Start with FrankenPHP. Of the three drivers, FrankenPHP offers the best balance of performance and simplicity for most teams: no PHP extension to compile, automatic HTTPS, and the binary downloads itself. Swoole is fastest but hardest to debug; RoadRunner sits in between.
- Canary it. Route a slice of production traffic to the Octane stack behind your load balancer and watch memory growth, error rates, and tail latency for at least a week before cutting over fully.
The Decision in One Paragraph
Start with PHP-FPM — it’s the safe default that works with everything and requires minimal configuration. When your traffic grows and your profiling shows the framework bootstrap eating a meaningful share of request time on CPU-bound endpoints, that’s your signal to evaluate Octane. Measure your own workload on your real traffic, not someone else’s benchmark table. The right answer for your app is the one your numbers support — and for plenty of apps, that answer stays PHP-FPM.
Further Reading & References
- Laravel Octane official documentation — installation, server prerequisites, memory leak management, concurrent tasks.
- PHP-FPM vs Laravel Octane: Real Benchmarks (2026) — Deploynix’s full wrk benchmark with throughput, latency, and memory tables (source of the figures quoted above).
- Laravel Octane (FrankenPHP) vs PHP-FPM: what I measured, and why we went back — Mattias Geniar’s honest post-mortem on running Octane in production and reverting.
- Laravel Octane vs PHP-FPM: A Deep Dive into Modern PHP Performance — dev.to walkthrough with a hands-on benchmark setup.
- FrankenPHP Laravel integration docs — worker mode options, HTTPS, and the
octane:frankenphpcommand flags. - Laravel Octane vs PHP-FPM for AI Workloads — analysis of the same benchmarks with a focus on tail latency.
Facts and benchmark figures verified 1 October 2026 against the Laravel documentation and the sources linked above.



