Laravel Octane: State Leakage &amp; Memory Management | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. Octane Worker Lifecycle, State Leakage, and Memory Management in Production

 Octane Worker Lifecycle, State Leakage, and Memory Management in Production
============================================================================

 Laravel Octane keeps workers alive across requests, which means static state, resolved singletons, and stale data can bleed between users. Learn exactly where leakage happens and how to prevent it.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 16 Aug 2026 · Updated 16 Aug 2026 · 3 min read

ShareCopy linkCopied

 ![Octane Worker Lifecycle, State Leakage, and Memory Management in Production](https://cdn.msaied.com/554/8cc265358b47e59601a66d1e247eba9a.png) 

  On this page +1. [Why Octane Changes Everything About Application State](#why-octane-changes-everything-about-application-state)
2. [The Worker Lifecycle in Detail](#the-worker-lifecycle-in-detail)
3. [Common Leakage Patterns](#common-leakage-patterns)
4. [1. Singletons That Accumulate State](#1-singletons-that-accumulate-state)
5. [2. Static Properties](#2-static-properties)
6. [3. Resolved Auth / Tenant Context](#3-resolved-auth-tenant-context)
7. [Memory Management](#memory-management)
8. [Max Requests Per Worker](#max-requests-per-worker)
9. [Watching for Leaks with memory\_get\_usage()](#watching-for-leaks-with-codememory-get-usagecode)
10. [Practical Checklist Before Deploying to Octane](#practical-checklist-before-deploying-to-octane)
11. [Takeaways](#takeaways)

 Why Octane Changes Everything About Application State
-----------------------------------------------------

Traditional PHP-FPM boots the entire Laravel application on every request and discards it afterwards. Octane inverts that model: a worker boots once, then handles thousands of requests inside the same process. The performance gains are real, but the contract your code must honour changes fundamentally.

Understanding the worker lifecycle is not optional — it is the difference between a fast application and one that leaks user data across requests.

The Worker Lifecycle in Detail
------------------------------

When Octane starts (Swoole or RoadRunner), each worker:

1. Boots the Laravel application (`Application::boot()`).
2. Resolves and caches all service-provider bindings.
3. Enters a request loop, calling `handle()` for each incoming HTTP request.
4. Resets a curated set of framework state between requests via **Octane's request lifecycle hooks**.

Octane ships with a list of "resettable" services (session, auth, database connections, etc.). Everything outside that list persists across requests unless you explicitly reset it.

Common Leakage Patterns
-----------------------

### 1. Singletons That Accumulate State

```php
// AppServiceProvider
$this->app->singleton(CartService::class, function () {
    return new CartService(); // holds items in a property
});

```

The `CartService` instance is created once per worker. If `addItem()` mutates an internal array, request B sees request A's cart.

**Fix — use `scoped()` instead of `singleton()`:**

```php
$this->app->scoped(CartService::class, CartService::class);

```

`scoped()` bindings are flushed by Octane between requests automatically.

### 2. Static Properties

```php
class FeatureFlags
{
    private static array $resolved = [];

    public static function get(string $flag): bool
    {
        return self::$resolved[$flag] ??= self::resolve($flag);
    }
}

```

Static properties survive the entire worker lifetime. A flag resolved for user A is returned to user B.

**Fix — flush in an Octane listener:**

```php
// OctaneServiceProvider or AppServiceProvider
use Laravel\Octane\Facades\Octane;

Octane::tick('flush-feature-flags', function () {
    FeatureFlags::flush();
})->everyRequests(1);

```

Or better, avoid static caches entirely and use the request-scoped IoC container.

### 3. Resolved Auth / Tenant Context

Multi-tenant apps often resolve the current tenant early and store it somewhere global. Under Octane that context sticks.

```php
// Dangerous under Octane
app()->instance('current.tenant', $tenant);

```

**Fix — use `OctaneServiceProvider` flush hooks:**

```php
use Laravel\Octane\Contracts\ServesStaticFiles;
use Laravel\Octane\Events\RequestReceived;
use Laravel\Octane\Events\RequestTerminated;

Event::listen(RequestReceived::class, function ($event) {
    $event->sandbox->forgetInstance('current.tenant');
});

```

The `$event->sandbox` is the per-request application clone Octane creates. Flushing on `RequestReceived` ensures a clean slate.

Memory Management
-----------------

Workers do not restart between requests, so memory grows. Two practical controls:

### Max Requests Per Worker

```ini
# octane config
'max_requests' => 500,

```

Octane gracefully restarts a worker after it has served this many requests. This is your safety net against slow leaks.

### Watching for Leaks with `memory_get_usage()`

```php
Octane::tick('memory-check', function () {
    if (memory_get_usage(true) > 128 * 1024 * 1024) {
        logger()->warning('Worker memory high', [
            'bytes' => memory_get_usage(true),
        ]);
    }
})->everyRequests(50);

```

Log and alert; do not silently let workers balloon to gigabytes.

Practical Checklist Before Deploying to Octane
----------------------------------------------

- Audit every `singleton()` binding — replace with `scoped()` where state is request-specific.
- Search the codebase for `static $` properties that cache data.
- Ensure third-party packages are Octane-compatible (check their issues trackers).
- Set a sane `max_requests` (200–1000 depending on memory profile).
- Add `RequestReceived` listeners to flush any global context (tenant, locale overrides).
- Run `php artisan octane:install` and review the generated `OctaneServiceProvider`.

Takeaways
---------

- Octane workers are long-lived; PHP-FPM assumptions about request isolation no longer hold.
- Prefer `scoped()` over `singleton()` for any service that touches request-specific data.
- Static properties are the hardest leaks to spot — grep for them before going live.
- Use `RequestReceived` and `RequestTerminated` events to flush custom global state.
- `max_requests` is not a workaround; it is a required production safety valve.

- [laravel](https://www.msaied.com/public/articles?search=laravel)
- [octane](https://www.msaied.com/public/articles?search=octane)
- [performance](https://www.msaied.com/public/articles?search=performance)
- [swoole](https://www.msaied.com/public/articles?search=swoole)
- [memory](https://www.msaied.com/public/articles?search=memory)

 Frequently asked questions 
---------------------------

  What is the difference between `singleton()` and `scoped()` in an Octane context?`singleton()` resolves once per worker process and persists across all requests that worker handles. `scoped()` resolves once per request lifecycle; Octane flushes scoped bindings between requests, giving you isolation without the overhead of a full re-boot.

   Does Octane automatically protect against all state leakage?No. Octane resets a curated list of framework-owned services (auth, session, database connections). Any application-level singletons, static properties, or globally bound instances you introduce are your responsibility to flush via Octane's request lifecycle events.

   How do I test for state leakage before deploying to production?Run your test suite with `OCTANE\_TESTING=true` and fire multiple sequential requests in a single process using Octane's built-in test helpers. Also inspect memory growth with `memory\_get\_usage()` across a batch of requests in a staging environment under realistic load.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleJob Batching with Laravel Horizon: Reliable Async Workflows at Scale](https://www.msaied.com/public/articles/job-batching-with-laravel-horizon-reliable-async-workflows-at-scale) [Next articleModular Monolith in Laravel: Enforcing Bounded Contexts Without a Microservice Tax](https://www.msaied.com/public/articles/modular-monolith-in-laravel-enforcing-bounded-contexts-without-a-microservice-tax)  

   On this page
-------------

1. [Why Octane Changes Everything About Application State](#why-octane-changes-everything-about-application-state)
2. [The Worker Lifecycle in Detail](#the-worker-lifecycle-in-detail)
3. [Common Leakage Patterns](#common-leakage-patterns)
4. [1. Singletons That Accumulate State](#1-singletons-that-accumulate-state)
5. [2. Static Properties](#2-static-properties)
6. [3. Resolved Auth / Tenant Context](#3-resolved-auth-tenant-context)
7. [Memory Management](#memory-management)
8. [Max Requests Per Worker](#max-requests-per-worker)
9. [Watching for Leaks with memory\_get\_usage()](#watching-for-leaks-with-codememory-get-usagecode)
10. [Practical Checklist Before Deploying to Octane](#practical-checklist-before-deploying-to-octane)
11. [Takeaways](#takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
