Skip to Content
πŸŽ‰ Bref 3.0 is released. Read more β†’
DocumentationSymfonyKeeping the Kernel alive

Keeping the Symfony Kernel alive between requests

This is an advanced approach aimed at optimizing performance. If you are just starting with Bref, this approach is not recommended because it is more complex to set up and can lead to unexpected issues.

By default, Bref uses PHP-FPM to handle HTTP requests. This means that the Symfony Kernel is restarted for every request. This is not a problem for most applications, but if you want to optimize performance, you can keep the Symfony Kernel alive between requests. This approach is similar to Laravel Octane, or running Symfony with RoadRunnerΒ .

Usage

The Bref Symfony Bridge integrates with the Symfony Runtime component. This means that Bref can natively set the Symfony Kernel as the handler for Lambda functions, without going through PHP-FPM:

serverless.yml
functions: app: - handler: public/index.php + handler: App\Kernel # Switch from PHP-FPM to the "function" runtime: - runtime: php-84-fpm + runtime: php-84 environment: + # The Symfony process will restart every 100 requests + BREF_LOOP_MAX: 100

BREF_LOOP_MAX sets the number of requests handled before the PHP process restarts. It defaults to 1: without it, the Kernel is not kept alive. The process also restarts after any request that fails with an uncaught exception, regardless of BREF_LOOP_MAX.

The App\Kernel will be retrieved via Symfony Runtime from public/index.php. If you don’t have a public/index.php, read the custom bootstrap file section.

How it works

Traditionally, Bref runs Symfony applications with the PHP-FPM runtime. By switching to the Function runtime, Bref loads the Symfony Kernel directly and can keep it alive between requests (controlled by BREF_LOOP_MAX).

Note that the execution model of AWS Lambda is unchanged: the entire Lambda instance is frozen between requests. The Symfony Kernel is kept alive in memory, but it is not running. When a new request comes in, the Lambda instance is thawed and the request is handled.

The main risks with this approach are memory leaks and global state. If your application has memory leaks, the memory usage will increase over time and eventually reach the Lambda limit. This can be mitigated by setting BREF_LOOP_MAX to a low value, so that the Symfony Kernel is restarted regularly. If your application uses global state, it will be shared between requests, which can be a disaster security-wise.

Services that keep state between requests must reset it by implementing Symfony’s ResetInterface (or the kernel.reset tag). Some bundles do not, for example EasyAdmin (symfony-bridge#58Β ) and KnpPaginatorBundle (symfony-bridge#59Β ). Test your application with several consecutive requests before deploying it to production.

Custom bootstrap file

If you do not have a public/index.php file, you can create a file that returns the kernel (or any PSR-11 container), for example kernel.php at the root of the project:

kernel.php
<?php require_once __DIR__.'/vendor/autoload_runtime.php'; return function (array $context) { return new App\Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']); };

Then set the handler to <file>:<service id>: Bref requires the file, gets the container from the kernel it returns, and uses the service with that ID as the handler.

serverless.yml
functions: app: handler: kernel.php:App\Kernel runtime: php-84 environment: BREF_LOOP_MAX: 100
Last updated on