The PHP Bench

PHP ORMs 2026

Comprehensive ORM benchmarks for every scenario.

Imports
1
Inbox Rows
1
Runs
312
Metrics
16,224
Matrices
52
Scenarios
6
Fastest Stack
Atlas
Storage
all-engines
Speed
0.060988s

Fastest Combinations

Atlas
all-engines · 2.0.1
0.060988s
Cycle
all-engines · 2.16.0
0.068316s
PHPFUIBatch
all-engines · 3.0.3
0.077969s
PHPFUI
all-engines · 3.0.3
0.084018s
Propel2
all-engines · 6cb272b6
0.097015s
DivergenceV2
all-engines · 2.1.4
0.099256s
ActiveRecord
all-engines · 2.0.6
0.103456s
Doctrine
all-engines · 3.6.2
0.123545s
DivergenceV3
all-engines · 3.2.0
0.125526s
Yii
all-engines · 2.0.54
0.128644s
RedBean
all-engines · 5.7.5
0.159354s
CakeCached
all-engines · 5.3.3
0.172560s
Cake
all-engines · 5.3.3
0.174024s
Eloquent
all-engines · 13.2.0
0.271510s

Inbox

ID Status Runner Runtime File
#1 processed runner-20260329222123 39.501s
avg 0.126606s
results-20260329203643-74505162-default-20260329-203643.csv

How Scenario Families Shift Rankings

Family Pressure Why It Changes Speed Avg Runtime
simple baseline row shape Shows framework overhead with very little field-mapping noise, so identity-map, query builder, and per-record object cost dominate. 0.099689s
canary 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. 0.154049s
int_fixed 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. 0.123969s
float_fixed numeric conversion and precision paths Decimal and floating-point mapping can trigger extra normalization work, especially on update verification and dirty-state comparison. 0.141195s
string_fixed 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. 0.118621s
string_variable 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. 0.122112s
Operation Shape Why Models Move
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.

Storage Engine Curve

sqlite-memory
0.069814s
mariadb
0.127033s
sqlite-file
0.142422s
postgresql
0.167155s

Scenario Families

simple
0.099689s
string_fixed
0.118621s
string_variable
0.122112s
int_fixed
0.123969s
float_fixed
0.141195s
canary
0.154049s

Imports

Run Host Status Rows Runtime Started
20260329203643-74505162 eimu
8.5.3
complete 16,224 39.501s
avg 0.126606s