Laravel Octane: State Leakage &amp; Memory Management | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Octane Worker Lifecycle, State Leakage, and Memory Management in Production        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)

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

  #laravel   #octane   #performance   #swoole   #memory  

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

     16 Aug 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

  11 sections  

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

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Foctane-worker-lifecycle-state-leakage-and-memory-management-in-production-2&text=Octane+Worker+Lifecycle%2C+State+Leakage%2C+and+Memory+Management+in+Production) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Foctane-worker-lifecycle-state-leakage-and-memory-management-in-production-2) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  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. 

      Q02  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. 

      Q03  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. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Job Batching with Laravel Horizon: Reliable Async Workflows at Scale](https://cdn.msaied.com/553/b794b736bfd84f3cbcc6218319916544.png) laravel queues horizon 

### Job Batching with Laravel Horizon: Reliable Async Workflows at Scale

Learn how to combine Laravel's job batching API with Horizon's queue supervision to build fault-tolerant async...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/job-batching-with-laravel-horizon-reliable-async-workflows-at-scale) [ ![Contextual Eloquent Casts: Custom Cast Classes, Value Objects, and Inbound-Only Transforms](https://cdn.msaied.com/552/a7825c0c6f53d934f84fce522573eafb.png) laravel eloquent value-objects 

### Contextual Eloquent Casts: Custom Cast Classes, Value Objects, and Inbound-Only Transforms

Go beyond primitive casts. Learn how to build custom Eloquent cast classes that hydrate value objects, handle...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Aug 2026     1 min read  

  Read    

 ](https://msaied.com/articles/contextual-eloquent-casts-custom-cast-classes-value-objects-and-inbound-only-transforms) [ ![Contextual Eloquent Scopes: Binding Query Logic to Domain State at Runtime](https://cdn.msaied.com/551/dc00bc1e6fb2999c99a0b5b8fb42a8c3.png) laravel eloquent architecture 

### Contextual Eloquent Scopes: Binding Query Logic to Domain State at Runtime

Learn how to attach runtime-aware query scopes to Eloquent models using the service container, avoiding scatte...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/contextual-eloquent-scopes-binding-query-logic-to-domain-state-at-runtime) 

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

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
