The PHP Bench

PHP ORMs 2026

Comprehensive ORM benchmarks for every scenario.

Latest run 20260928011232-b9eaed5b kaiju · PHP 8.5.11 ·
14
ORM adapters
4
storage engines
16
scenarios
3
uploads

Runtime comparison

Mean time per scenario run with warmup runs excluded, sorted by runtime. Each framework does different work, so read these next to the features you need from an ORM.

Init Insert Read Update Delete
  1. Doctrine 3.6.2 sqlite-file 130 ms
  2. Cake 5.3.3 sqlite-file 308 ms
  3. CakeCached 5.3.3 sqlite-file 310 ms
  4. PHPFUIBatch 3.0.3 sqlite-file 924 ms
  5. ActiveRecord 2.0.6 sqlite-file 1,614 ms
  6. Atlas 2.0.1 sqlite-file 2,151 ms
  7. Cycle 2.16.0 sqlite-file 2,157 ms
  8. PHPFUI 3.0.3 sqlite-file 2,230 ms
  9. Propel2 6cb272b6 sqlite-file 2,231 ms
  10. DivergenceV3 3.2.0 sqlite-file 2,285 ms
  11. Yii 2.0.54 sqlite-file 2,311 ms
  12. RedBean 5.7.5 sqlite-file 2,347 ms
  13. Eloquent 13.2.0 sqlite-file 2,528 ms

Storage engines

Mean across every framework measured on each engine.

  • sqlite-file 1,656 ms

Scenario families

Mean across every framework and engine for each row shape.

  • simple 167 ms
  • string_variable 1,025 ms
  • string_fixed 1,054 ms
  • float_fixed 1,221 ms
  • int_fixed 1,233 ms
  • canary 1,471 ms

What the workloads measure

Every framework runs the same scenarios. The row shape and the operation mix decide where each one spends its time.

simple

167 ms
baseline row shape

Shows framework overhead with very little field-mapping noise, so identity-map, query builder, and per-record object cost dominate.

canary

1,471 ms
mixed nullable and cast-heavy fields

Wide records amplify hydration, casting, dirty-checking, and serialization overhead. Frameworks with expensive attribute normalization usually spread out here.

int_fixed

1,233 ms
narrow scalar writes

A near-floor for typed persistence. If an ORM is still slow here, the cost is usually framework machinery rather than payload complexity.

float_fixed

1,221 ms
numeric conversion and precision paths

Decimal and floating-point mapping can trigger extra normalization work, especially on update verification and dirty-state comparison.

string_fixed

1,054 ms
predictable text hydration

Fixed-length text stresses text field assignment without the variability of large blobs, so column-count and hydration strategy matter more than payload churn.

string_variable

1,025 ms
application-style text records

This is the closest to a real CRUD app payload. Variable strings and notes fields widen the gap between lightweight row mappers and heavier active-record layers.

Warmup vs hot runs
Run 1 is a warmup pass. Hot-path rankings exclude it so adapter boot, metadata discovery, and first-query setup do not drown out steady-state behavior.
Insert and indexed schemas
Indexed variants make inserts more expensive because each row write updates secondary indexes. ORMs that already have heavy unit-of-work overhead get exposed harder there.
Read all vs read probes
Read All rewards efficient bulk hydration. Random and tail probes reveal per-query setup cost, identity lookup behavior, and how much work happens for tiny result sets.
Update with verification
Updates are followed by read-back verification. That means slow dirty-checking, full-row writes, cast normalization, and post-update reads all feed into the total.
Delete phase
Delete cost is not just delete. The harness verifies the row is actually gone, so frameworks with slow teardown or follow-up lookup behavior pay twice.
Total runtime
Total runtime is a whole-machine workload number: init, insert, every read shape, every update shape, verification passes, and delete.

Runs

Imported uploads from signed runners. Open a run for its machine and per-engine detail.

Run Host Status Samples Runtime Started
20260928011232-b9eaed5b kaijuPHP 8.5.11 complete 7,488of 8,320 runs 2h 29m 1savg 1,194 ms
20260831062427-083dfb94 eimuPHP 8.5.3 complete 144of 160 runs 12.384savg 86.0 ms
20260329203643-74505162 eimuPHP 8.5.3 complete 312of 312 runs 39.501savg 127 ms

Inbox

ID Status Runner Runtime File
#3 processed kaiju 2h 29m 1savg 1,194 ms results-20260928011232-b9eaed5b-default-20260928-011232.csv received
#2 processed eimu 12.384savg 86.0 ms results-20260831062427-083dfb94-v3-3-0-staged-sqlite-memory-20260831-062427.csv received
#1 processed runner-20260329222123 39.501savg 127 ms results-20260329203643-74505162-default-20260329-203643.csv received