The Laravel team announced the release of Laravel Octane in 2021, its purpose being to improve the speed and performance of Laravel applications by reducing the request/response time by caching an instance of a Laravel dependency container in RAM memory. This process is done by tools called Swoole and RoadRunner.
In this post, we will be conducting a quick-start guide on how to optimize your Laravel apps with Octane, taking into consideration a benchmark analysis to demonstrate the performance differences between RoadRunner, Swoole, and Nginx.
Jump ahead:
The Replay is a weekly newsletter for dev and engineering leaders.
Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.
Laravel Octane is a package that serves Laravel apps with Swoole or RoadRunner to help improve performance.
Conventional Laravel apps are served from webservers like Apache, Nginx, and Lighttpd, which with every request spawns a PHP-FPM worker. This approach causes an overhead for creating processes and booting Laravel apps on every request, which is referred to as a stateless approach, as none of PHP processes are re-used on each request.
While Swoole and RoadRunner still use worker processes for all requests, they only serve the first request to boot the framework (dependency containers), and any other ones are from the bootstrapped version of the framework.
Now that weβve gone over the details of what comprises Octane and what it does, letβs get started with putting it into action.
Hereβs how to begin:
β― composer create-project laravel/laravel laravel-octane β― composer require laravel/octane β― php artisan octane:install Which application server you would like to use?: [0] roadrunner [1] swoole > 0
RoadRunner or Swoole is needed to serve your application since they are both external packages, but most times RoadRunner will be installed after app server selection. If it is not, use the command below to install it manually:
composer require spiral/roadrunner
Installing Swoole can be a bit different, as itβs a PHP extension and not a package and requires few procedures. The following command is used to install it and get started with setup procedures:
pecl install swoole
(Note: We wonβt cover the procedures for installing and setting up Swoole with PHP, but hereβs a simple guide to do it)
Start your app with the following command, then navigate to your browser.
php artisan octane:start INFO Server running⦠Local: http://127.0.0.1:8000
You can also specify which technology/server to use and how many threads to run, based on your environmentβs CPU threads, as shown below.
php artisan octane:start --workers=4 --server=roadrunner
The project used in this post is a simple page with a little populated data. We will be changing the app server (RoadRunner, Swoole, and Nginx) at every stage of the test, so as to evaluate and compare the performance of each server by using AutoCannon.
This process will help you in making a decision on which app server is most suitable for your project.
AutoCannon is capable of generating lots of traffic, even when running on a single multi-core CPU; we will be running a benchmark for 10 seconds with 100 concurrent connections, 10 pipeline connections, and 3 worker threads to fire requests.
β― autocannon http://127.0.0.1:8000 -d 10 -w 3 -c 100 -p 10 Running 10s test @ http://127.0.0.1:8000 100 connections with 10 pipelining factor 3 workers / βββββββββββ¬βββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬βββββββββββββ¬ββββββββββββ¬ββββββββββ β Stat β 2.5% β 50% β 97.5% β 99% β Avg β Stdev β Max β βββββββββββΌβββββββββΌββββββββββΌββββββββββΌββββββββββΌβββββββββββββΌββββββββββββΌββββββββββ€ β Latency β 201 ms β 1773 ms β 3175 ms β 3304 ms β 1854.07 ms β 657.15 ms β 4201 ms β βββββββββββ΄βββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄βββββββββββββ΄ββββββββββββ΄ββββββββββ βββββββββββββ¬ββββββ¬βββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ β Stat β 1% β 2.5% β 50% β 97.5% β Avg β Stdev β Min β βββββββββββββΌββββββΌβββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββ€ β Req/Sec β 0 β 0 β 503 β 576 β 475.3 β 166.71 β 440 β βββββββββββββΌββββββΌβββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββ€ β Bytes/Sec β 0 B β 0 B β 4.13 MB β 4.73 MB β 3.91 MB β 1.37 MB β 3.62 MB β βββββββββββββ΄ββββββ΄βββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ Req/Bytes counts sampled once per second. # of samples: 30 6k requests in 10.02s, 39.1 MB read
β― autocannon http://127.0.0.1:8000 -d 10 -w 3 -c 100 -p 10 Running 10s test @ http://127.0.0.1:8000 100 connections with 10 pipelining factor 3 workers - βββββββββββ¬βββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬βββββββββββββ¬ββββββββββββ¬ββββββββββ β Stat β 2.5% β 50% β 97.5% β 99% β Avg β Stdev β Max β βββββββββββΌβββββββββΌββββββββββΌββββββββββΌββββββββββΌβββββββββββββΌββββββββββββΌββββββββββ€ β Latency β 119 ms β 1692 ms β 2314 ms β 2587 ms β 1617.82 ms β 574.62 ms β 3153 ms β βββββββββββ΄βββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄βββββββββββββ΄ββββββββββββ΄ββββββββββ βββββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ β Stat β 1% β 2.5% β 50% β 97.5% β Avg β Stdev β Min β βββββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββ€ β Req/Sec β 366 β 366 β 544 β 861 β 546.3 β 124.68 β 366 β βββββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββ€ β Bytes/Sec β 3.01 MB β 3.01 MB β 4.47 MB β 7.08 MB β 4.49 MB β 1.02 MB β 3.01 MB β βββββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ Req/Bytes counts sampled once per second. # of samples: 30 6k requests in 10.02s, 44.9 MB read
To benchmark the app via Nginx, we need to setup Laravel Valet , and then proceed to run the same command; but in this case, we use 127.0.0.1, because it runs on port 80.
β― autocannon http://127.0.0.1 -d 10 -w 3 -c 100 -p 10 Running 10s test @ http://127.0.0.1 100 connections with 10 pipelining factor 3 workers / βββββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬βββββββββ¬ββββββββββββ¬ββββββββββ¬βββββββββ β Stat β 2.5% β 50% β 97.5% β 99% β Avg β Stdev β Max β βββββββββββΌβββββββββΌβββββββββΌβββββββββΌβββββββββΌββββββββββββΌββββββββββΌβββββββββ€ β Latency β 111 ms β 169 ms β 202 ms β 235 ms β 166.22 ms β 23.1 ms β 290 ms β βββββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄βββββββββ΄ββββββββββββ΄ββββββββββ΄βββββββββ βββββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬βββββββββ¬ββββββββββ β Stat β 1% β 2.5% β 50% β 97.5% β Avg β Stdev β Min β βββββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌβββββββββΌββββββββββ€ β Req/Sec β 4551 β 4551 β 5691 β 6343 β 5718.8 β 464.3 β 4548 β βββββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌββββββββββΌβββββββββΌββββββββββ€ β Bytes/Sec β 2.13 MB β 2.13 MB β 2.67 MB β 2.98 MB β 2.68 MB β 218 kB β 2.13 MB β βββββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄βββββββββ΄ββββββββββ Req/Bytes counts sampled once per second. # of samples: 32 0 2xx responses, 62950 non 2xx responses 64k requests in 10.01s, 29.5 MB read
According to the bechmark analysis, you will notice that Nginx ran a total number of 64k requests, which is a lot more than the requests made by both Swoole and RoadRunner, which is around 12k, or 6k each.
In conclusion, I would consider Swoole and RoadRunner a better option in this scenario, but that doesnβt necessarily mean Nginx or other web servers such as Apache and lighttpd should not be considered, as they are still used by many to serve millions of websites with large concurrent users and are still great choices.
Thanks for reading, let me know your own opinion about Laravel Octane (or other web servers) and which you like using in your own projects.
Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not
server-side
$ npm i --save logrocket
// Code:
import LogRocket from 'logrocket';
LogRocket.init('app/id');
// Add to your HTML:
<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>

Promise.all still relevant in 2025?In 2025, async JavaScript looks very different. With tools like Promise.any, Promise.allSettled, and Array.fromAsync, many developers wonder if Promise.all is still worth it. The short answer is yes β but only if you know when and why to use it.

Discover what’s new in The Replay, LogRocket’s newsletter for dev and engineering leaders, in the October 29th issue.

Learn about the new features in the Next.js 16 release: why they matter, how they impact your workflow, and how to start using them.

Test out Meta’s AI model, Llama, on a real CRUD frontend projects, compare it with competing models, and walk through the setup process.
Hey there, want to help make our blog better?
Join LogRocketβs Content Advisory Board. Youβll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now
2 Replies to "A quick guide to optimizing Laravel apps with Octane"
I don’t understand what the statistics mean, I can infer that more requests are worse (thus, NGINX is less performant), but why is that the case?
I am also confused. According to your results all the Nginx results are all 400’s i.e. errors. Laravel also has rate limiting by default. Are you sure Swoole and RoadRunner aren’t rate limited.