Revision: Fri, 22 Sep 2023 11:05:11 GMT
v3.1 – outdated
This version of the documentation is outdated. Consider upgrading your project to Spiral Framework 3.8
Edit this page

Application Lifecycle

Spiral Framework can work using classic Nginx/PHP-FPM setup. But the highest effectiveness can be achieved using an embedded application server (based on RoadRunner). The server creates a set of php processes for each dispatching/communication method (HTTP, GRPC, Queue, TCP, etc.).

Every PHP process will only work within a single request/task. It allows you to write code the way you would typically do in classic frameworks (share nothing approach). You can also use every library as you did in the past with only minor exceptions.

Read more about Framework and application server symbiosis here. Read about PSR-7 request flow here.

Application Server

The RoadRunner Application Server is installed using the RoadRunner Bridge integration package. In the spiral/app skeleton, this package is already installed and configured.

Learn more about the RoadRunner Bridge:

You can configure the number of workers, memory limits, and other extensions using .rr.yaml file:

version: '2.7'

  listen: tcp://

  command: "php app.php"
  relay: pipes

# serve static files
  dir: "public"

# HTTP plugin settings
  middleware: [ "gzip", "static" ]
    dir: "public"
    forbid: [ ".php", ".htaccess" ]
    num_workers: 2
      max_worker_memory: 100

To set the number of workers for HTTP:

    num_workers: 4

Developer Mode

To force worker reload after every request (full debug mode) and limit processing to a single worker, add a debug option:

      debug: true

You can read more about RoadRunner here.

Application Kernel

Every worker will contain a single application instance. Default application skeleton(s) are based on spiral/boot.

The package allows quick application instantiation via static factory method create and allows you to run the created application via the run method:

$app = \App\App::create(['root' => __DIR__])->run();

Application Kernel initiates your application state and IoC configuration using a set of bootloaders:

class App extends Kernel
     * List of components and extensions to be automatically registered
     * within system container on application start.
    protected const LOAD = [
        // Environment configuration
        // Core Services
        // Security and validation
        // ...

The bootloaders will only be invoked once, without request/task context. After that, application will stay in the process memory permanently. Since the application bootload only happens once for many requests, you can add many components and extensions without performance penalty (still, watch the memory consumption).


There are a couple of limitations to be aware of.

Memory Leaks

Since the application stays in memory for a long time, even a small memory leak might lead to process restart. RoadRunner will monitor memory consumption and perform a soft reset, but it is best to avoid memory leaks in your application source code.

Though Framework and all of its components are written with memory management in mind, you still have to make sure that your domain code is not leaking.

Application State

Framework includes a set of instruments to simplify the development process and avoid memory/state leaks such as IoC Scopes, Cycle ORM, Immutable Configs, Domain Cores, Routes, and Middleware.


Event Description
Spiral\Boot\Event\Bootstrapped The Event will be fired after all bootloaders from SYSTEM, LOAD and APP sections initialized.
Spiral\Boot\Event\Serving The Event will be fired before looking for a dispatcher for handling incoming requests in a current environment.
Spiral\Boot\Event\DispatcherFound The Event will be fired when a dispatcher for handling incoming requests in a current environment is found.
Spiral\Boot\Event\DispatcherNotFound The Event will be fired when an application dispatcher is not found.
Spiral\Boot\Event\Finalizing The Event will be fired when finalizer are executed before running finalizers.