Framework Competition — Cold Start

PHP-FPM simulation, fresh boot per request: the application boots for every request (harness cold mode, opcache retained). FPM's own worker management is not simulated — real FPM keeps its worker alive and adds nginx + FastCGI overhead on top of this boot, so these are lower bounds for real FPM latency (see the real-fpm view for the measured version).

PHP 8.3.33 · Linux 6.8.0-139-generic · php-fpm mode · OPcache: yes · 50 iterations per run over 30 runs · charts show the median as a faint bar + dot with the fastest → p95 range, lower is better

Boot model: boot included: a fresh framework rebuild is timed inside every request

Framework startup — boot + teardown (cold + FPM rebuild + warm)
Framework startup — boot + teardown (cold + FPM rebuild + warm)
Total response times
Total response times

Feature benchmarks

Routing

GET / — dispatches a plain request through the router and returns a rendered template — no database access.

Routing
ORM / Active Record

GET /items — loads one page of the 1,000 seeded rows through each framework's ORM / Active Record layer: 20 items plus a COUNT for the pagination total.

ORM / Active Record
Query Builder

GET /items-qb — builds the same page of 20 items with each framework's query builder instead of its ORM, so the two data-access styles can be compared directly.

Query Builder
REST API (JSON)

GET /api/items — serves the same page of items as a JSON response rather than HTML, which adds serialization to the ORM work.

REST API (JSON)
AOP (Aspect-Oriented)

GET /features/aop — runs a request through an interceptor pipeline — logging, retry and middleware aspects wrapped around the handler. Only frameworks with an AOP layer take part.

AOP (Aspect-Oriented)
Cache

GET /features/cache — reads a COUNT(*) over the 1,000 rows through the framework's cache with a 10-second TTL, so a hit costs no database work and a miss runs the query.

Cache
Database Events

GET /features/db-events — inserts one event row per request and lets the framework's database events fire around that write.

Database Events
Event Dispatcher

GET /features/events — dispatches an in-process event to registered listeners.

Event Dispatcher
Validation

GET /features/validation — validates a payload with the framework's own validator.

Validation
Config

GET /features/config — resolves a value from the framework's config repository.

Config
Request-Scoped Services

GET /features/request-scoped — resolves a service scoped to the request from the container.

Request-Scoped Services
Rate Limiter

GET /features/rate-limit — checks a cache-backed rate limiter.

Rate Limiter

Latency by endpoint (ms, trimmed mean — lower is better) (sub-line: boot + handle + post-response cleanup, which sum to the total) — cold rows and charts are end-to-end: each iteration pays a fresh framework boot inside the request clock (FPM story)

RequestWorkloadAzeraLaravelSymfonySpiralCodeIgniterCakePHP
GET /no DB — routing + template only2.23 0.06+2.17+0.006.56 4.16+2.40+0.003.83 1.63+2.20+0.008.40 4.66+3.72+0.023.13 0.02+3.09+0.023.23 0.38+2.85+0.00
GET /items20 of 1000 items (page 1, + COUNT)3.52 0.06+3.45+0.018.08 4.07+4.01+0.006.36 1.64+4.72+0.009.78 4.50+5.25+0.034.38 0.03+4.33+0.026.02 0.40+5.62+0.00
GET /items/11 item by id3.22 0.05+3.16+0.017.82 4.10+3.72+0.005.40 1.60+3.80+0.009.47 4.45+5.00+0.024.53 0.03+4.48+0.025.78 0.40+5.38+0.00
POST /items1 row upserted (sentinel #999999)3.63 0.05+3.57+0.017.84 4.08+3.76+0.007.32 1.66+5.65+0.019.63 4.48+5.13+0.024.64 0.03+4.59+0.026.01 0.40+5.61+0.00
GET /items-qb20 of 1000 items (page 1, + COUNT)3.22 0.06+3.16+0.007.65 4.15+3.50+0.004.88 1.62+3.26+0.009.18 4.52+4.64+0.024.32 0.03+4.27+0.024.53 0.40+4.13+0.00
GET /items-qb/11 item by id3.19 0.05+3.14+0.007.52 4.14+3.38+0.004.82 1.60+3.22+0.009.08 4.50+4.56+0.024.52 0.03+4.47+0.024.50 0.39+4.11+0.00
POST /items-qb1 row upserted (sentinel #999997)3.37 0.06+3.31+0.007.54 4.14+3.40+0.006.62 1.63+4.99+0.009.27 4.52+4.73+0.024.77 0.03+4.72+0.024.66 0.40+4.26+0.00
GET /api/items20 of 1000 items as JSON3.18 0.06+3.12+0.009.39 4.12+5.27+0.005.83 1.61+4.22+0.009.04 4.48+4.53+0.034.32 0.03+4.27+0.025.84 0.41+5.43+0.00
GET /api/items/11 item by id as JSON3.17 0.06+3.10+0.019.25 4.12+5.13+0.005.42 1.63+3.79+0.008.95 4.50+4.43+0.024.52 0.03+4.47+0.025.95 0.42+5.53+0.00
POST /api/items1 row upserted (sentinel #999998)3.27 0.06+3.20+0.017.97 4.10+3.87+0.007.01 1.65+5.35+0.019.01 4.46+4.53+0.024.68 0.03+4.63+0.026.01 0.41+5.60+0.00
GET /features/aopno DB — interceptor pipeline5.40 0.06+5.34+0.009.32 4.19+5.13+0.006.41 1.62+4.78+0.0111.2 4.5+6.7+0.0——
GET /features/cacheCOUNT(*) of 1000 rows, cached 10s (miss = query)3.75 0.05+3.70+0.008.19 4.16+4.03+0.005.73 1.60+4.13+0.009.61 4.50+5.09+0.024.29 0.03+4.24+0.025.04 0.39+4.65+0.00
GET /features/logno DB — buffered log handlers3.10 0.05+3.05+0.007.03 4.10+2.93+0.004.10 1.64+2.46+0.008.69 4.48+4.19+0.02——
GET /features/retryno DB — retry policy3.07 0.06+3.01+0.007.05 4.09+2.96+0.004.13 1.61+2.52+0.008.65 4.45+4.18+0.02——
GET /features/pipelineno DB — middleware pipeline2.40 0.06+2.34+0.007.08 4.09+2.99+0.004.09 1.61+2.48+0.008.64 4.44+4.18+0.02——
GET /features/db-events1 event row INSERTed per request3.82 0.05+3.77+0.008.11 4.12+3.99+0.006.09 1.62+4.46+0.019.72 4.47+5.23+0.024.63 0.03+4.58+0.025.40 0.41+4.99+0.00
GET /features/eventsno DB — in-process listeners3.77 0.06+3.71+0.007.74 4.11+3.63+0.004.92 1.61+3.31+0.009.38 4.46+4.90+0.024.49 0.03+4.44+0.024.23 0.40+3.83+0.00
GET /features/validationno DB — validator run3.01 0.06+2.95+0.008.65 4.14+4.51+0.004.80 1.61+3.19+0.008.85 4.46+4.37+0.024.70 0.03+4.65+0.024.56 0.40+4.16+0.00
GET /features/configno DB — config lookup2.27 0.06+2.21+0.007.19 4.17+3.02+0.004.12 1.61+2.51+0.008.62 4.44+4.16+0.023.46 0.03+3.41+0.023.42 0.40+3.02+0.00
GET /features/request-scopedno DB — scoped service resolve2.32 0.06+2.26+0.007.20 4.18+3.02+0.004.14 1.62+2.52+0.008.63 4.45+4.16+0.023.41 0.03+3.36+0.023.37 0.40+2.97+0.00
GET /features/rate-limitno DB — cache-backed limiter2.43 0.07+2.36+0.007.39 4.13+3.26+0.004.14 1.62+2.52+0.008.81 4.43+4.36+0.023.42 0.03+3.37+0.023.60 0.41+3.19+0.00