Laravel Octane is here

Roberto Butti
4 min readApr 6, 2021

With Laravel Octane you can serve your Laravel application using a powerful Application Server for PHP, like Swoole and/or Roadrunner.

Laravel Octane has the responsibility to boot correctly your application once, keeps it in memory, it cleans object states and manages the instance of the objects across the requests.

You can obtain source code of Laravel Octane here: https://github.com/laravel/octane

Normally, the application and all objects are instanced once for each request. With Laravel Octane the application , the framework instance and the object instances are shared across the requests. It means that the developer needs to consider the state of some objects (remember some of that are instanced once at the boot time of the worker), in this case Laravel Octane helps to manage the states of the objects.

What is Roadrunner? Roadrunner is an Application Server written in Go, for serving PHP application.

What we are going to do:

  • install a new Laravel application from scratch;
  • install Laravel Octane;
  • install Roadrunner Application Server;
  • launch Laravel Octane;
  • install a HTTP Benchmarking tool.

And then we will execute a comparison benchmark with Nginx and Laravel Octane (Roadrunner).

Install and Setup your Application

I’m going to create a new Laravel application from scratch. So first of all, I need to install or update “laravel” tool. It is useful for creating a new Laravel application:

composer global require laravel/installer

Then i can create the new Laravel application:

laravel new laravel-octane

Then enter in the new directory:

cd laravel-octane

I suggest to create this application in the directory served by Valet. So you can reach this through your Browser via Nginx : http://laravel-octane.test

Then you can install and setup Laravel Octane:

composer require laravel/octane
php artisan octane:install

Laravel Octane creates the bridge between you Laravel application and the Application Server, but at the end you need to install the application server. In this case we will use Roadrunner:

composer require spiral/roadrunner
./vendor/bin/rr get-binary
chmod u+x rr

You don’t need to launch that. If you are familiar with Roardrunner, usually you need to create .rr.yaml file and launch rr command. Instead, with Laravel Octane, the following Artisan Command will take in charge to launch the application server with the right configuration. To launch the application server and expose your Laravel application:

php artisan octane:start

If everything is fine, you could open your browser and access to your application at the URL: http://127.0.0.1:8000

If you want to change the port, you can use the port option:

php artisan octane:start --port=8002

You can specify also how many worker processes will be started. The default is the number of logical CPUs. If you know exactly what are you doing, you can use workers option:

php artisan octane:start --port=8002 --workers=8

Execute test comparison, Nginx VS Roadrunner

In order to retrieve some insight about the performance and mimic a lot of concurrent traffic on your Laravel application, I’m going to use wrk https://github.com/wg/wrk. If you have a macOS and you are using Homebrew , you can install wrk:

brew install wrk

With Wrk you can generate a lot of concurrent request for a defined amount of time.

If you launch wrk in order to generate traffic:

I’m going to execute wrk with:

  • 4 threads to use;
  • 20 connections to keep open;
  • 10 secondo of duration of test.

So for testing Nginx:

wrk -t4 -c20 -d10s http://laravel-octane.test

For testing Laravel Octane (Roadrunner)

wrk -t4 -c20 -d10s http://laravel-octane.test:8000

The result are different.

For Nginx:

Launch wrk on Nginx

For Laravel Octane:

Launch wrk on Laravel Octane

Some considerations

The main difference with serving the Laravel application with Laravel Octane + Roadrunner instead of the classic Web server is:

  • The Application is bootstrapped once, and multiple request will share same resources;
  • The construct of the controller are called once (when the worker is instanced);
  • Think about what happens to “static” class attribute.

Let me explain this with an example.

Create 2 routes in routes/web.php:

use App\Http\Controllers\MainController;
Route::get('/', [MainController::class, 'index']);
Route::get('/show', [MainController::class, 'show']);

Create MainController.php in app/Http/Controllers directory where you:

  • define a static attribute (array) $list;
  • define index method where you append a random integer to the self::$list array;
  • define show method where you use and show the self::$list array
<?php// app/Http/Controllers/MainController.phpnamespace App\Http\Controllers;
use Illuminate\Http\Request;
class MainController extends Controller{
public static $list = [];
public function index() {
self::$list[]= \random_int(1,6);
return view('welcome');
}
public function show() {
return view('show', ["list" => self::$list]);
}
}

Then create a very basic blade file as resources/views/show.blade.php:

{{-- resources/views/show.blade.php --}}<h2>LIST:</h2><p>{{ implode(",",$list) }}</p><p>DONE</p>

If you call multiple time http://laravel-octane.test:8080/ it will be called the index method so, some integers will be added to your list. The static list is shared across the request on the same worker. So if you try to call http://laravel-octane.test:8080/show it will be called show method where list attribute will be used.

So I think that working in an Application Server context for a PHP developer is a great changes specially thinking about the life cycle of the request. A PHP developer typically is used to have all the Framework instanced in every request.

Do you agree with those considerations?

Feel free to drop some comments and/or feedbacks.

--

--

Roberto Butti

I’m technophile. Vuejs and Laravel enthusiast! #vuejs #laravel. I love #coding