What a year of Laravel Octane in production taught me
Memory leaks, state bleeding between requests, and why not every service provider should boot once.

Octane makes Laravel fast by keeping the application in memory between requests. That is also exactly what makes it dangerous: anything you used to treat as request-scoped is now potentially process-scoped.
The leak that took a week to find
Our worker memory crept up by ~2 MB per thousand requests. The culprit was a singleton that cached the authenticated user:
$this->app->singleton(CurrentTenant::class, function ($app) {
return new CurrentTenant($app['request']->user());
});
On a classic PHP-FPM setup this is harmless. Under Octane, the first request's user sticks around for every request that worker serves afterwards.
What we changed
- Moved request-bound services to
scoped()bindings instead ofsingleton(). - Added the class to Octane's
flushlist where a rebind wasn't possible. - Ran a load test that asserts memory per worker stays flat.
If a service reads the request, the session, or the auth guard, it is not a singleton. Full stop.
Is it worth it?
| Metric | FPM | Octane (Swoole) |
|---|---|---|
| p50 latency | 48 ms | 11 ms |
| p99 latency | 210 ms | 64 ms |
| Servers | 6 | 2 |
Yes — but only once the team treats boot-time state as a shared resource.
Next note
One schema, two runtimes: API contracts with Zod→