Compiling PHP DTOs: The Path to 4.5M Hydrations per Second
A PHP 8.4 package compiles DTO hydration into per-class closures with opcache-backed caching and lazy ghosts, delivering up to 35x faster hydration.
Attribute-driven DTO libraries are pleasant to write but typically pay a reflection-and-dispatch tax on every call. A new PHP 8.4+ package called Simple Data Objects removes that cost by compiling a specialized closure per data class: plain properties become direct array reads, the generated code is persisted through an opcache-served cache, and PHP 8.4's lazy ghosts defer hydration until a property is actually touched.
The architecture unfolds in four steps: reflection runs once per class and is cached as immutable metadata, that metadata is compiled into a class-specific hydrator/serializer closure, the compiled source is persisted to disk so it can be warmed on deploy, and lazy ghosts plus a streaming lazyCollection() let hydration be skipped entirely for objects that are never read.
Benchmarked against a popular full-featured alternative, the package measures roughly 35x faster flat-DTO hydration, 37x faster serialization, and about 50x lower peak memory when streaming 50,000 rows. The tradeoffs are explicit: PHP 8.4 only, constructor-promoted readonly properties required, no setters or runtime magic. For teams with DTOs sitting on the hot path who mainly need fast hydrate/validate/serialize rather than a broader toolkit, it's a concrete performance win.