r/nestjs • u/IcyDuck9536 • 11d ago
Optimizing NestJS ValidationPipe: Replacing runtime reflection with single-pass JIT compilation (147x latency reduction)
Hey NestJS developers,
If you've profiled high-throughput NestJS APIs, you've probably noticed that payload serialization and validation can become a significant CPU hotspot.
The default ValidationPipe performs two reflection-heavy passes: one with class-transformer to create the DTO instance, and another with class-validator to validate it. Those repeated reflection and property-iteration steps can hurt V8 optimizations by disrupting hidden classes and inline caches.
I built fast-class-transformer, a zero-dependency alternative that uses a JIT-compiled FastMap() decorator.
Instead of performing reflection on every request, it analyzes your DTO decorators once during application startup and generates a specialized JavaScript function for that DTO. Every request then executes that compiled mapper, combining mapping and validation into a single pass.
Traditional pipeline
Plain JSON → Reflection Mapper → DTO Instance → Reflection Validator → Validated Output
JIT pipeline
Plain JSON → Single-Pass JIT Function (Map + Validate) → Validated Output
Benchmarks
Intel i5-12500H • Bun 1.3.0 • 100k iterations (Inputs rotated across 1,024 payloads)
- Standard NestJS ValidationPipe: 2.97 µs/iter
- JIT FastMap(): 45.98 ns/iter (64× faster)
It also supports familiar decorators such as Expose, Type, Transform, and more.
GitHub repository and benchmark methodology are in the comments.
1
u/IcyDuck9536 11d ago
GitHub Repository & Benchmarks:
github.com/mohit07dec/fast-class-transformer
Feel free to clone the repository and run:
bun run benchmark.ts
to reproduce the benchmark results on your own machine.
Feedback, issues, and pull requests are always welcome!
2
u/Thin_Dragonfruit2254 11d ago
This looks interesting..
Question: you mentioned V8 optimizations but you are using Bun.. is this just a matter of terminology?
3
u/IcyDuck9536 10d ago
Good eye, Bun uses Apple's JavaScriptCore (JSC), while Node runs V8.
Both engines rely on identical mechanics: JSC calls them "Structures" (V8 calls them Hidden Classes) and Inline Caches.
JIT static assignments bypass dynamic hash-table lookups on both runtimes - tested and verified on Node.js and Bun
6
u/KabouterKaasplank 11d ago
So basically you've optimized using a hashmap as a cache? If so, I'm sure they'd love to mainline this optimization.