Serverless PHP runtime12 min read

Bref: running PHP on AWS Lambda

A guide to Bref, the open source Composer package and toolkit for running PHP applications serverless on AWS Lambda, with a local readiness example.

PHP compatibility and project lifecycle

Supported PHP versions, Bref versions and framework versions are unknown from the supplied packet. The learning track uses PHP 8.4 with PHP 8.5 planned, and the local example targets PHP 8.4 only. The packet names Laravel and Symfony integrations and AWS Lambda as the target platform.

Official sources checked 2026-10-22. Browser lessons on this site run PHP 8.5.

It relies only on the single official Bref documentation page supplied for this guide. Anything that page does not state is marked unknown.

What Bref is

According to the documentation, Bref is an open source Composer package. It helps you deploy PHP applications to AWS and run them on AWS Lambda. It also makes it easier to use other AWS services such as S3, RDS and SQS. The documentation lists four things Bref provides:

  • documentation
  • PHP runtimes for AWS Lambda
  • deployment tooling
  • integrations for Laravel and Symfony

Classification

Bref is best described as a serverless PHP runtime toolkit for one platform, AWS Lambda. It is not a standalone PHP interpreter or language implementation, and it is not a web server like Swoole or Open Swoole. It is also not a framework or a CMS. Laravel and Symfony are frameworks, and Bref only provides integrations for them. The source does not mention Drupal, so this guide makes no claim about Drupal. PHP core is a separate project that Bref packages for Lambda. The source does not say how.

Lifecycle status is unknown here. The page gives no version, support policy or deprecation information.

Execution model

Serverless here means the cloud provider manages the servers. Bref uses Function as a Service: code runs only when invoked, and billing is per use. The page says applications scale automatically.

The documentation says Lambda invocations happen per HTTP request, per SQS job, per CLI command and per cron task. Each invocation has a maximum execution time of 15 minutes. Long-running processes such as queue workers and websocket servers are not run on Lambda.

Request lifetimes and persistent workers

A classic PHP-FPM request starts clean and discards its state at the end. A persistent worker keeps the process alive and reuses it for many requests. The source says warm Lambda invocations can be very fast and that cold starts happen. It does not say how PHP memory is reused between invocations, so that detail is unknown from this packet.

For learning purposes, treat any reuse as possible and avoid depending on it. In any persistent-worker setup, state can leak between requests. Static properties, global variables, singletons, open connections, caches and request-specific data such as the current user can all carry over. A worker can then show one user's data to the next, or grow in memory. Cleanup means resetting or avoiding that state at the end of every unit of work. In practice:

  • Keep request data in local variables or per-request objects.
  • Reset static properties and singletons, or avoid them.
  • Close or validate connections.
  • Keep durable data in external services.

The source also says instances have independent, ephemeral filesystems. Do not use local disk for anything that must be shared or kept.

Architecture

The documented architecture has these parts:

  • Application code is mounted read-only.
  • Many instances may run in parallel, each with its own ephemeral filesystem.
  • Logs go to stderr, which Lambda centralizes in AWS CloudWatch.
  • Sessions go to a database or Redis.
  • Databases and caches run separately, for example in RDS or ElastiCache.
  • Uploaded and generated files go to S3.
  • The serverless CLI configures and deploys the application, using a serverless.yml file and AWS CloudFormation.

The documentation says these are the same constraints as auto-scaled containers. Preparing for them also prepares an application for horizontal scaling in general.

Practical use cases

The documentation lists APIs, websites, workers, batch scripts and event-driven microservices. It calls jobs and cron tasks very good candidates. It says Bref integrates with Laravel Queues and Symfony Messenger, and that SQS and Lambda integrate natively so you do not run workers yourself. Websites can keep assets in S3 behind CloudFront. Legacy applications can be hard to migrate because sessions and uploads often need rework.

Installation approach

Bref is installed through Composer and deployed with the serverless CLI. The packet does not give exact install commands, package names, runtime identifiers or plugin settings, and this guide does not invent them. Follow the official installation documentation linked from the Bref docs, and check which PHP versions Bref supports there. Compatibility is unknown from this packet.

Strengths

  • You do not set up or maintain servers.
  • Billing is per request.
  • Scaling is automatic.
  • Deep Laravel and Symfony integrations exist.
  • SQS and Lambda integrate natively for queue work.
  • Each microservice can scale independently.

Limitations

  • About 0.2% of production requests are cold starts, which the page says can add 200 ms to 500 ms or more.
  • HTTP requests and uploads are limited to about 4 MB, so large uploads should go straight to S3 with pre-signed URLs.
  • Each invocation is limited to 15 minutes.
  • Websocket servers and long-running workers do not fit on Lambda. The page points to API Gateway WebSocket as an alternative.
  • The page says there is currently no native Laravel Echo integration.
  • The page calls Lambda a poor choice when latency must stay below 100 ms for 100% of requests.
  • It is tied to AWS.
  • Terraform is less documented than the serverless CLI route.

Deployment

This guide does not provision or deploy anything. Deployment means running the serverless CLI against an AWS account, which needs credentials and cloud resources. That is outside this lesson. The example below is a local, framework-free script that shows the habits the documentation asks for: log to stderr, treat the disk as ephemeral, read configuration from the environment, and keep state out of the process. It does not use any Bref API. The included serverless.example.yml is a placeholder skeleton, and the Bref-specific entries must come from the official setup documentation.

The example is a PHP 8.4 command-line exercise. It is not a browser exercise.

Further reading

The official Bref documentation page is listed in the links. It leads to the installation guide, the explanation of how Lambda and Bref work, case studies and use-case guides.

Practical examples

These examples have not been run in a live environment yet. Commands and versions follow the official documentation linked on this page; check them before relying on them, and report a problem if one does not work.

Serverless-readiness check with the PHP CLI server (no Bref API, no deployment)

A local PHP 8.4 script that mirrors habits the Bref docs recommend: logging through error_log to stderr, treating the filesystem as ephemeral, and reading configuration from environment variables. It needs no Composer dependencies and no cloud access. The serverless.example.yml is an illustrative placeholder only and is never deployed.

src/Readiness.php

<?php

declare(strict_types=1);

namespace Demo;

final class Readiness
{
    /**
     * @return array<string, mixed>
     */
    public static function report(string $appDir): array
    {
        $tmp = sys_get_temp_dir();

        return [
            'php_version' => PHP_VERSION,
            'app_env' => getenv('APP_ENV') !== false ? getenv('APP_ENV') : 'unset',
            'app_dir_writable' => is_writable($appDir),
            'temp_dir' => $tmp,
            'temp_dir_writable' => is_writable($tmp),
            'notes' => [
                'Code may be read-only on Lambda; do not write into the app directory.',
                'Filesystems are ephemeral and per instance; use S3 for files and a database or Redis for sessions.',
                'Log to stderr (error_log here) instead of files.',
            ],
        ];
    }
}

public/index.php

<?php

declare(strict_types=1);

require_once __DIR__ . '/../src/Readiness.php';

use Demo\Readiness;

$report = Readiness::report(dirname(__DIR__));

error_log('readiness check handled for ' . ($_SERVER['REQUEST_URI'] ?? 'cli'));

header('Content-Type: application/json');
echo json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR), "\n";

serverless.example.yml

# Illustrative placeholder only.
# Bref-specific plugin, runtime and handler entries are intentionally omitted.
# Copy them from the official Bref setup documentation before any real use.
service: readiness-demo

provider:
  name: aws

Install and run

php -v
php -S 127.0.0.1:8080 -t public
curl http://127.0.0.1:8080/

Expected behavior

With PHP 8.4 installed, the server listens only on 127.0.0.1:8080. The curl request returns pretty-printed JSON containing php_version, app_env (unset unless APP_ENV is exported), the writable checks and three notes. The server terminal shows a log line from error_log.

This is a local PHP CLI built-in server demo. It is not Bref, does not run on Lambda and does not deploy anything. The writable checks will probably differ on Lambda, which the docs describe as read-only for application code. The serverless.example.yml is incomplete on purpose. Requires PHP 8.4 on the host.