One customer sees another customer’s cart. No crash, no error in the log. That is the bug Laravel Octane brings to an old codebase, and the benchmarks are the least interesting part of the story.

Octane is out in beta, Swoole and RoadRunner became first-class overnight. In FPM every request gets a fresh application. Boot, handle, die. The model forgives everything. Under Octane the framework boots once and workers reuse it. Bootstrap cost drops to near zero, hence the pretty numbers. But every singleton is now shared between requests, and between users.

class Cart
{
    public array $items = [];
}

// AppServiceProvider
$this->app->singleton(Cart::class);

In FPM this is sloppy but harmless. Under Octane the second user gets the first user’s items. Nothing crashes. One customer quietly sees another’s data. The worst bugs, the invisible kind. Same trap with static properties, memoized “per-request” caches, an authenticated user stored somewhere too convenient.

Octane flushes and rebinds a lot of framework internals between requests, and there is config to reset your own services. But the framework cannot guess which of your singletons hold request state. That audit is manual. On an old codebase it is real work.

Two more items on the bill. Memory grows across thousands of requests, so a small leak FPM erased for free becomes a graph you must watch, plus a worker restart policy. And with Swoole a blocking call blocks the whole worker, so one slow external HTTP request holds a slot hostage.

Whether it pays depends on where your time goes. Bootstrap is a big slice, high-RPS API with light endpoints: Octane is close to free performance. p95 is database queries: you made the fast part faster and bought a new class of bugs. Profile before, not after.

I grepped our project for singleton(. I stopped counting at the one that holds the current user.