The goal of this repository is to benchmark popular frameworks to be used as a REST API in their optimal configuration.
- Default offering of the framework.
- Optimized suggested state for the framework.
- HelloWorld:
GET /ping: Returns a simple{message: 'pong'}JSON response.- Command:
ab -t 10 -c 10 http://server.address/ping
- Command:
- Read:
GET /users: Returns a list of 50 users from the database.- Command:
ab -t 10 -c 10 http://server.address/users
- Command:
- Write:
POST /users: Saves a user to the database.- Command:
ab -t 10 -c 10 -p data.json -T 'application/json' http://server.address/users
- Command:
- Compute:
GET /compute: Computes the first 10,000 Fibonacci numbers.- Command:
ab -t 10 -c 10 http://server.address/compute
- Command:
- ApacheBench
- PHP 8.x or later
- Swoole PECL extension (for Laravel Octane)
- All of the projects are using SQLite to avoid heavy setup.
- Laravel
- Run
composer install - Run
touch database/database.sqlitefrom thelaraveldirectory. - Run
cp .env.example .envfollowed byphp artisan key:generatefrom thelaraveldirectory. - Open
.envfile and set theDB_CONNECTIONvariables value tosqliteand comment out all the remainingDB_*variables. - Run
php artisan migratefrom thelaraveldirectory. - To run the project without octane, run:
php artisan serve - To run the project with octane (make sure swoole pecl ext is installed and enabled):
php artisan octane:installand thenphp artisan octane:start
- Run
- Lumen
- Run
composer install - Run
touch database/database.sqlitefrom thelumendirectory. - Run
cp .env.example .envfollowed byphp artisan key:generatefrom thelumendirectory. - Open
.envfile and set theDB_CONNECTIONvariables value tosqliteand comment out all the remainingDB_*variables. - Run
php artisan migratefrom thelumendirectory. - To run the project, run:
php -S localhost:8000 -t public
- Run
- Symfony:
- Run
composer install - Run
touch var/data.dbfrom thesymfonydirectory. - Create a
.envfile and set theDATABASE_URLto:DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" - Run
php bin/console doctrine:migrations:migrateand confirm if asked. - To run the project, run:
php -S localhost:8000 -t public
- Run
- Express:
- Run
touch database.sqlitefrom theexpressjsdirectory - Run:
npm install - Run:
npm start
- Run
Other than the above mentioned endpoints, each project has two helper endpoints: /truncate and /generate which truncates the users table and generates 50 user records with same key-value pairs to achieve byte-fairness across all frameworks. Performance isn't measured against these two endpoints.
The data.json file in each project is used during the test for the Write criteria.
- Memory: 8GB Apple Unified Memory
- CPU: 8-Core Apple Silicon
| Framework | Request Per Second |
|---|---|
| Laravel | 366.19 |
| Laravel (Octane) | 1548.85 |
| Lumen | 1567.74 |
| Symfony | 145.17 |
| Express | 1021.3 |
| Framework | Request Per Second |
|---|---|
| Laravel | 159.39 |
| Laravel (Octane) | 930.98 |
| Lumen | 246.95 |
| Symfony | 106.92 |
| Express | 1545.86 |
| Framework | Request Per Second |
|---|---|
| Laravel | 238.62 |
| Laravel (Octane) | 921.45 |
| Lumen | 513.8 |
| Symfony | 106.48 |
| Express | 1189.17 |
| Framework | Request Per Second |
|---|---|
| Laravel | 336.79 |
| Laravel (Octane) | 1436.07 |
| Lumen | 1438.68 |
| Symfony | 122.29 |
| Express | 984.36 |
[P.S.: The results may be subject to change as we add more frameworks.]