Skip to content
benchmarks

Numbers with a gate attached.

Performance claims are only interesting when they are reproducible and enforced. These figures ship with a suite that runs in CI against the latest stable Zod, and the harness is in the repository for you to run unchanged.

0.00×geomean
VLD v3.0.11Zod 4.6.4 · 1.00×
  • Ten scenarios covering strings, numbers, nullish, optional, unions, arrays and objects.
  • One million safeParse operations per scenario, twenty-one runs, warm-up discarded.
  • Every result is semantic-checked — a fast wrong answer fails the gate.
  • Enforced in CI on every commit, so a regression cannot be merged quietly.

higher is better

Simple string3× faster
VLD620M ops/s
Zod 4.6.4206.7M ops/s
Number / positive int9.1× faster
VLD253M ops/s
Zod 4.6.427.8M ops/s
Nullish parse30.7× faster
VLD214M ops/s
Zod 4.6.47.0M ops/s
Optional parse3.8× faster
VLD213M ops/s
Zod 4.6.456.1M ops/s
Array / object parse1.7× faster
VLD49M ops/s
Zod 4.6.428.8M ops/s
Union parse3.3× faster
VLD39M ops/s
Zod 4.6.411.8M ops/s
Discriminated union4.1× faster
VLD35M ops/s
Zod 4.6.48.5M ops/s

V2 method memoization vs V1 vs Zod

lower is better · 1M safeParse

schemaVLD V1VLD V2ZodV2 vs Zod
string().min(1).email()22ms22ms50ms2.3× faster
number().int().positive()12ms6ms39ms6.5× faster
object({ a: str, b: num })12ms11ms18ms1.6× faster
realistic API (10 fields)276ms243ms767ms3.2× faster
optional · bundles zod on demand

Run the head-to-head yourself.

This builds the same nine-field schema twice — once with @oxog/vld, once with the published zod you have on disk — then checks that both agree on a valid and an invalid payload before timing them.

  • id: uuid
  • name: string().min(2).max(100)
  • email: email
  • age: int().min(18).max(120)
  • score: number().min(0).max(1000)
  • role: enum(admin,user,guest)
  • tags: array(string).min(1)
  • active: boolean
  • url: url

100,000 safeParse calls per library, best of five runs. A single schema on a single machine is not a benchmark suite — treat the ratio as an indication, and reproduce the full suite locally.

Press run. Zod is fetched only at this moment, so it costs the page nothing until you ask for it.

terminalreproduce
# the official suite, gated against the latest stable Zodnpm run benchmark # fail the build if a performance floor is missednpm run benchmark:guard # allocation and retention per schema shapenpm run benchmark:memory # cold-start cost of importing the packagenpm run benchmark:startup # the full release gate: tests, parity, exports, performancenpm run release:check

How to read these numbers

A validator's cost is dominated by shape complexity, not by the library's overhead alone. The 620M ops/sec figure is a single string check with one constraint; the object and array cases sit near 49M ops/sec because they allocate output objects.

The meaningful comparison is always per-scenario and against the same baseline. That is why the CI gate fails on a regression in any scenario rather than on the average.

Your hardware, Node version and payload shape will move these numbers. The reproduction commands above run the identical harness, and the benchmark sources are plain Node scripts with no framework.