Skip to content

Repository files navigation

PHP Framework Benchmark

PHP Framework Benchmark

A real-world HTTP benchmark comparing popular PHP frameworks under identical conditions. Each framework runs inside its own Docker container with Nginx + PHP-FPM, default configuration, and no special optimizations enabled.

Frameworks

FrameworkVersionPortTemplate Engine
Webrium58001Webrium View
Laravel11.x8002Blade
CodeIgniter4.x8003PHP native
Symfony7.x8004Twig

Test Endpoints

EndpointWhat it measures
GET /bench/renderFramework boot + view rendering with a static dataset
GET /bench/jsonFramework boot + JSON response serialization

Each endpoint returns the same 10-user dataset. No database queries are involved in these tests. All responses are validated as HTTP 200.

Environment

  • OS: Ubuntu 22.04 (Docker)
  • PHP: 8.2
  • Server: Nginx + PHP-FPM (default worker settings)
  • OPcache: enabled (default configuration)
  • Benchmark tool: wrk - 4 threads, 100 connections, 30 seconds
  • Hardware: 16 CPU cores, 16GB RAM

Results

Tested on: June 19, 2026 All frameworks run with default configuration. No caching layers, no query optimizers, no custom FPM tuning. CPU and memory are sampled roughly once per second throughout each run (not just before/after), and reported as average / peak across the test.

/bench/render

FrameworkReq/secAvg latencyp99 latencyCPU avgCPU peakMem avgMem peak
Webrium11,8658.5ms14.6ms540%565%37 MiB38 MiB
Symfony3,67927.5ms56.3ms513%540%43 MiB44 MiB
CodeIgniter3,10532.5ms62.6ms500%525%41 MiB42 MiB
Laravel465219.8ms592.7ms480%506%70 MiB81 MiB

/bench/json

FrameworkReq/secAvg latencyp99 latencyCPU avgCPU peakMem avgMem peak
Webrium13,5267.5ms11.7ms567%583%38 MiB40 MiB
Symfony4,26723.4ms32.9ms527%543%44 MiB45 MiB
CodeIgniter3,36229.7ms43.0ms515%528%40 MiB41 MiB
Laravel392257.1ms638.6ms492%509%90 MiB99 MiB

Latency distribution - /bench/render

PercentileWebriumSymfonyCodeIgniterLaravel
p508.2ms26.2ms31.0ms186.3ms
p758.5ms27.2ms32.2ms267.3ms
p908.9ms28.9ms34.2ms364.2ms
p9914.6ms56.3ms62.6ms592.7ms
Max57.3ms194.6ms216.3ms996.2ms

Latency distribution - /bench/json

PercentileWebriumSymfonyCodeIgniterLaravel
p507.3ms23.1ms29.3ms222.5ms
p757.6ms24.2ms30.6ms341.9ms
p907.9ms25.4ms32.3ms442.4ms
p9911.7ms32.9ms43.0ms638.6ms
Max47.8ms61.1ms56.3ms1150ms

Notable observations

All four frameworks left CPU headroom on this 16-core machine. With CPU sampled throughout the run, every framework sat in the ~480-580% range - i.e. each used between 5 and 6 cores' worth of CPU out of 16 available, so none of them came close to saturating the host. This means CPU was not the bottleneck for any framework; the limit was per-request overhead and the fixed wrk client load (4 threads, 100 connections), not raw CPU capacity. The real differentiator is how many requests each framework delivered for that similar CPU spend: Webrium turned ~5-6 cores into ~11,900 req/s on /bench/render, while Laravel produced ~465 req/s from a comparable CPU load. This throughput-per-core gap is what the old idle before/after snapshots completely hid.

Memory is where the frameworks separate cleanly. Webrium, CodeIgniter, and Symfony all held steady between ~37 and ~45 MiB across both endpoints, with very little spread between average and peak. Laravel used noticeably more - ~70 MiB average (81 MiB peak) on render and ~90 MiB average (99 MiB peak) on JSON - and showed a wider gap between average and peak, indicating more memory churn per request.

Laravel's JSON endpoint was slower than its render endpoint (392 vs 465 req/s). Laravel's response()->json() pipeline triggers additional service-resolution layers compared to rendering a Blade view, and this shows up as both lower throughput and higher memory use (90 MiB average on JSON vs 70 MiB on render).

Symfony outperformed CodeIgniter despite being a heavier framework. In production mode, Symfony compiles its routing and service container into cached PHP files, reducing per-request overhead. CodeIgniter does not apply this level of compilation caching.

Latency distributions stayed tight for the three faster frameworks. Webrium, Symfony, and CodeIgniter all showed low standard deviation and a small p50-to-p99 spread, confirming stable test conditions. Laravel's distribution was much wider (e.g. 222ms p50 rising to 639ms p99 on JSON), consistent with a framework operating close to its throughput ceiling under this load.

Note on sampling: because each docker stats reading takes roughly one second, a 30-second run yields about 15 samples per framework. The averages and peaks above are computed from those samples. Increasing the run duration or lowering the sample interval would tighten these figures further.

How to run

Requirements

  • Docker and Docker Compose
  • wrk
# Install wrk on Ubuntu/Debian
sudo apt update && sudo apt install -y wrk

Clone and start

git clone https://github.com/webrium/php-benchmark.git
cd php-benchmark

Place your framework source files in the corresponding volume directories:

laravel-app/ <- Laravel application files
webrium-app/ <- Webrium application files
codeigniter-app/ <- CodeIgniter application files
symfony-app/ <- Symfony application files

Build and start all containers:

docker compose up -d --build

The first run takes a few minutes as Composer installs each framework. Check progress with:

docker compose logs -f

Verify endpoints

curl -s -o /dev/null -w "%{http_code}" http://localhost:8001/bench/render # Webrium
curl -s -o /dev/null -w "%{http_code}" http://localhost:8002/bench/render # Laravel
curl -s -o /dev/null -w "%{http_code}" http://localhost:8003/bench/render # CodeIgniter
curl -s -o /dev/null -w "%{http_code}" http://localhost:8004/bench/render # Symfony

All should return 200.

Run the benchmark

chmod +x benchmark.sh
./benchmark.sh 2>&1| tee results.txt

Results are saved to results.txt. The script runs each framework sequentially with a 30-second cooldown between tests and validates that all responses return HTTP 200.

Stop containers

docker compose down

Project structure

php-benchmark/
|-- docker-compose.yml
|-- benchmark.sh
|-- check_status.lua
|-- database.sql
|-- docker/
| |-- Dockerfile.laravel
| |-- Dockerfile.webrium
| |-- Dockerfile.codeigniter
| |-- Dockerfile.symfony
| |-- nginx-laravel.conf
| |-- nginx-webrium.conf
| |-- nginx-codeigniter.conf
| |-- nginx-symfony.conf
| |-- entrypoint-laravel.sh
| |-- entrypoint-webrium.sh
| |-- entrypoint-codeigniter.sh
| `-- entrypoint-symfony.sh
|-- laravel-app/
|-- webrium-app/
|-- codeigniter-app/
`-- symfony-app/

Methodology

  • Each framework runs in an isolated Docker container on Ubuntu 22.04
  • PHP 8.2 with OPcache enabled at default settings
  • Nginx + PHP-FPM with default worker configuration - no tuning applied
  • A 30-second cooldown period between each test run allows CPU and memory to return to idle
  • CPU and memory are sampled with docker stats roughly once per second while the load test is running, and reported as average and peak across all samples - not just a single before/after snapshot
  • All responses are validated via a Lua script - only HTTP 200 responses are counted
  • Frameworks are tested in the same order each run

Challenging the results

If you believe these results do not reflect fair or accurate conditions for a specific framework, you are welcome to open an issue.

Please include:

  • The framework and version you are questioning
  • The specific configuration change you believe would make the comparison fairer
  • A technical explanation of why the current setup disadvantages that framework

Our goal is to produce results that are accurate, reproducible, and conducted under equal conditions for all frameworks. If a configuration error is found, we will re-run the benchmark and update the results.

All frameworks in this benchmark run with their standard default configuration. No special optimizations, custom OPcache tuning, JIT settings, or FPM worker counts have been applied beyond what ships out of the box.

License

MIT

About

HTTP benchmark comparing PHP frameworks (Webrium, Laravel, CodeIgniter, Symfony) under identical Nginx + PHP-FPM conditions.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages