themattosdev/leakless

Zero state and memory leak prevention for PHP persistent runtimes (FrankenPHP & Laravel Octane)
47 1
Install
composer require themattosdev/leakless
Latest Version:v0.9.0
PHP:^8.2
License:MIT
Last Updated:Sep 10, 2026
Links: GitHub  ·  Packagist
Maintainer: jmgoncalves97

Overview

In traditional PHP-FPM, worker processes terminate after each request, allowing the OS to wipe memory and state. Persistent runtimes like FrankenPHP, RoadRunner, Swoole, and Laravel Octane keep PHP in memory across thousands of requests. While significantly faster, long-running workers can suffer from unmonitored C-extension memory growth (outside the Zend VM heap), dangling database transactions, open file handles, and polluted global/static state.

Leakless is an autonomous runtime guardian and static analysis engine for any persistent PHP stack: it reads real Linux kernel RSS from /proc/self/statm, rolls back uncommitted PDO transactions, cleans runtime state with a zero-reflection resettables engine in finally blocks, gracefully recycles workers before OOM Killer strikes, and provides static analysis via PHPStan and Pest assertions.


Installation

# Runtime engine (production)
composer require themattosdev/leakless

# Developer tooling, CLI analyzer, and Pest assertions
composer require --dev themattosdev/leakless-dev

Usage

1. Vanilla PHP / FrankenPHP Loop

use TheMattos\Leakless\DTOs\Config;
use TheMattos\Leakless\Integrations\FrankenPhp\FrankenPhp;

FrankenPHP::run(
    app: function () {
        echo json_encode(['status' => 'ok']);
    },
    config: new Config(
        maxDriftMb: 64,
        maxRequests: 1000,
        resettables: [
            App\Services\CartSession::class,
            fn () => LegacyRegistry::$cache = [],
        ],
    ),
);

2. Laravel Octane (Zero-Config)

LEAKLESS_ENABLED=true
LEAKLESS_MAX_DRIFT_MB=64
LEAKLESS_CHECK_TRANSACTIONS=true
LEAKLESS_CHECK_FILE_DESCRIPTORS=false

In config/leakless.php, you can also register classes or callbacks to auto-reset:

'resettables' => [
    App\Services\CartSession::class,
    fn () => LegacyRegistry::$cache = [],
],

Note regarding Laravel Octane: Octane provides native scoped() bindings and a 'flush' list in config/octane.php. Leakless provides its compiled zero-reflection resettables engine and #[ResetOnRequest] attribute. It is at your own discretion which mechanism to use — you can rely on Octane's native mechanisms, use Leakless's resettables, or combine both seamlessly.

3. Declarative State Reset (#[ResetOnRequest])

Annotate properties or classes to automatically restore initial or default values between requests when registered in resettables:

use TheMattos\Leakless\Attributes\ResetOnRequest;

class UserContext
{
    // Static properties are reset when registering UserContext::class in 'resettables'
    #[ResetOnRequest]
    public static ?string $token = null;

    #[ResetOnRequest(default: 'guest')]
    public static string $role = 'guest';

    // Instance properties are reset when registering the object instance itself
    #[ResetOnRequest(default: [])]
    public array $permissions = [];
}
// In config/leakless.php:
'resettables' => [
    // Resets static #[ResetOnRequest] properties and static cleanup methods:
    UserContext::class,

    // To reset instance properties, register the resolved object instance or callback:
    // fn () => app(UserContext::class)->permissions = [],
],

Important: #[ResetOnRequest] does not automatically scan all classes across your application. To be reset at runtime, the target class (for static state) or object instance (for instance state) must be registered in 'resettables' or via $leakless->registerResetTarget().

4. Automated Testing (Pest & PHPUnit)

test('service executes cleanly without leaking memory or state', function () {
    // 1. Structural design check (no mutable static props or illegal constructor injections)
    expect(PaymentService::class)->toBeLeakless();

    // 2. Full request lifecycle check (PDO transactions, FDs, and Linux RSS drift)
    expect(function () {
        (new PaymentService())->processPendingTransactions();
    })->toRunCleanly(maxDriftMb: 0.25);

    // 3. Deep container/instance property snapshotting (detects runtime state mutations)
    expect(app())->toResetContainerState(function () {
        $this->postJson('/api/checkout', ['item' => 'pro']);
    });
});

5. Static Worker Linter CLI

vendor/bin/leakless analyze

Documentation

Full documentation, architecture guides, kernel memory details, and anti-pattern catalogues are available at:

👉 https://leakless.themattos.dev


Testing & Quality

# Run test suite
docker compose run --rm app vendor/bin/pest

# Code style
docker compose run --rm app vendor/bin/pint --test

# Static analysis (Level 9)
docker compose run --rm app composer analyse

License

Open-source software licensed under the MIT License.
Developed by Jonathan Gonçalves.

Related Packages

erirk/paypalpayment

laravel-paypalpayment is simple package help you process direct credit card paym...

0
gabrieloliverio/laravel5-generators

Database metadata-based generators for Laravel 5

1
doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database s...

628,058,007 9,707
laravel/framework

The Laravel Framework.

576,155,700 34,907
laravel/tinker

Powerful REPL for the Laravel framework.

485,678,092 7,440