RoadRunner: HTTP and PSR-7 worker

v3.5.1 2024-04-26 11:16 UTC



68747470733a2f2f706f7365722e707567782e6f72672f73706972616c2f726f616472756e6e65722f76657273696f6e 68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f73706972616c2f726f616472756e6e65723f7374617475732e737667 68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f73706972616c2f726f616472756e6e6572 68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73706972616c2f726f616472756e6e65722f6261646765732f7175616c6974792d73636f72652e706e67 68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646973636f72642d636861742d6d6167656e74612e737667 68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64642f73706972616c2f726f616472756e6e65723f7374796c653d666c61742d737175617265

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a service with the ability to extend its functionality on a per-project basis.

RoadRunner includes PSR-7/PSR-17 compatible HTTP and HTTP/2 server and can be used to replace classic Nginx+FPM setup with much greater performance and flexibility.

Official Website | Documentation


This repository contains the codebase PSR-7 PHP workers. Check spiral/roadrunner to get application server.


Ensure that your server is configured with the following PHP versions and extensions:

  • PHP >=8.1
  • ext-protobuf: This extension is optional but highly recommended for installation. Without it, performance may be up to 50% lower.
  • RoadRunner ^2023.3


To install application server and HTTP codebase:

composer require spiral/roadrunner-http nyholm/psr7

You can use the convenient installer to download the latest available compatible version of RoadRunner assembly:

composer require spiral/roadrunner-cli --dev

To download latest version of application server:

vendor/bin/rr get

You can use any PSR-17 compatible implementation.


To init abstract RoadRunner worker:


require __DIR__ . '/vendor/autoload.php';

use Nyholm\Psr7\Response;
use Nyholm\Psr7\Factory\Psr17Factory;

use Spiral\RoadRunner\Worker;
use Spiral\RoadRunner\Http\PSR7Worker;

// Create new RoadRunner worker from global environment
$worker = Worker::create();

// Create common PSR-17 HTTP factory
$factory = new Psr17Factory();

// Create PSR-7 worker and pass:
//  - RoadRunner worker
//  - PSR-17 ServerRequestFactory
//  - PSR-17 StreamFactory
//  - PSR-17 UploadFilesFactory
$psr7 = new PSR7Worker($worker, $factory, $factory, $factory);

while (true) {
    try {
        $request = $psr7->waitRequest();
    } catch (\Throwable $e) {
        // Although the PSR-17 specification clearly states that there can be
        // no exceptions when creating a request, however, some implementations
        // may violate this rule. Therefore, it is recommended to process the 
        // incoming request for errors.
        // Send "Bad Request" response.
        $psr7->respond(new Response(400));

    try {
        // Here is where the call to your application code will be located. 
        // For example:
        //  $response = $app->send($request);
        // Reply by the 200 OK response
        $psr7->respond(new Response(200, [], 'Hello RoadRunner!'));
    } catch (\Throwable $e) {
        // In case of any exceptions in the application code, you should handle
        // them and inform the client about the presence of a server error.
        // Reply by the 500 Internal Server Error response
        $psr7->respond(new Response(500, [], 'Something Went Wrong!'));

        // Additionally, we can inform the RoadRunner that the processing 
        // of the request failed.

Stream response

To send a response in a stream, set the $chunkSize property in PSR7Worker:

$psr7 = new PSR7Worker($worker, $factory, $factory, $factory);
$psr7->chunkSize = 512 * 1024; // 512KB

Now PSR7Worker will cut the response into chunks of 512KB and send them to the stream.

Early hints

To send multiple responses you may use the \Spiral\RoadRunner\Http\HttpWorker::respond() method with the endOfStream parameter set to false. This will send the response to the client and allow you to send additional responses.

/** @var \Spiral\RoadRunner\Http\PSR7Worker $psr7 */
$httpWorker = $psr7->getHttpWorker()
    ->respond(103, header: ['Link' => ['</style.css>; rel=preload; as=style']], endOfStream: false);

// End of stream will be sent automatically after PSR7Worker::respond() call
$psr7->respond(new Response(200, [], 'Hello RoadRunner!'));

try Spiral Framework


This codebase is automatically tested via host repository - spiral/roadrunner.


The MIT License (MIT). Please see LICENSE for more information. Maintained by Spiral Scout.