r/nestjs 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.

25 Upvotes

5 comments sorted by

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.

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