ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 48

  1. Blog

Zod vs Valibot: 1.14M vs 0.97M Parses

zod 4.6.5 vs valibot 1.5.0 on one nested user schema (uuid/email/age/tags/profile/enum). Warm medians after 2k warmup + 9×50k: zod.parse 1,144,494 ops/s vs valibot.parse 968,187 (~1.18×). safeParse fail: valibot 697,760 vs zod 415,523 (~1.7×). esbuild minify+gzip9: 452,999/92,636 B vs 85,126/15,422 B. Package trees ~6.1 MB vs ~1.9 MB. Fixture /workspace/bench-zod-valibot/.

Aditya Challa·5 October 2026·4 min read

Hands-on
On this page
  1. What I tested
  2. How wide was the parse gap?
  3. Does the bundle gap change the call?
  4. Should you switch schema libraries?
  5. Sources
  6. Related

I parsed one nested user object 50,000 times per round on this box: Zod 4.6.5 median 1.14M ops/s on the success path, Valibot 1.5.0 median 0.97M ops/s — about 1.18× in Zod’s favor here. The same schemas minified to 453 KB vs 85 KB (gzip 93 KB vs 15 KB).

Short answer: keep Zod 4 if you already ship it and want the faster happy-path parse on this shape. Pick Valibot when the client bundle budget is the constraint. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 00:30–00:35 IST.
  • Versions: zod 4.6.5, valibot 1.5.0, Node 22.20.0, esbuild for the bundle check.
  • Fixture: /workspace/bench-zod-valibot/. One object schema (uuid, email, int age, tags array, nested profile, enum role). Good payload and a bad payload (bad email, negative age, invalid role).
  • Timing: 2,000 warm iterations, then 9 rounds of 50,000 parse/safeParse calls each. Medians reported. Bundle: esbuild minify ESM browser build of export { z } from "zod" vs export * as v from "valibot", gzip -9.
  • Findings: zod.parse ok 1,144,494 ops/s (median 43.7 ms / 50k); valibot.parse ok 968,187 ops/s (51.6 ms). zod.safeParse ok 1,139,141; valibot.safeParse ok 979,417. On failures: valibot.safeParse 697,760 ops/s vs zod.safeParse 415,523 (~1.7× for Valibot). Package trees on disk: zod ~6.1 MB, valibot ~1.9 MB. Minify 452,999 B vs 85,126 B; gzip 92,636 B vs 15,422 B.
  • One surprise: Zod 4 beat Valibot on the success path for this schema; Valibot still dominated fail-path throughput and the shipped bundle.
  • Not tested: Zod codecs/transforms beyond this object, Valibot async pipes, TypeScript compile time, Deno/Bun, edge runtimes, schema codegen, Ajv.

How wide was the parse gap?

PathMedian ops/sMedian ms / 50k
zod.parse ok1,144,49443.7
valibot.parse ok968,18751.6
zod.safeParse ok1,139,14143.9
valibot.safeParse ok979,41751.1
zod.safeParse fail415,523120.3
valibot.safeParse fail697,76071.7

Same schema shape, same box. Happy-path parse favored Zod 4 here; invalid input favored Valibot. For lint/format cousins see Biome vs ESLint/Prettier and oxlint vs ESLint. For shipped JS weight, pair with size-limit vs bundlesize.

Does the bundle gap change the call?

Yes, if the schema library lands in the browser. Minified ESM was 453 KB for Zod vs 85 KB for Valibot; gzip -9 was 93 KB vs 15 KB (~6×). Installed package trees were ~6.1 MB vs ~1.9 MB. Server-only validation can ignore that; a form-heavy SPA should not.

Treat this as one object schema on Node 22, not a claim that Zod is always faster. Fail-path and bundle still lean Valibot.

Should you switch schema libraries?

SituationMy pick
Already on Zod 4 in a Node APIStay on Zod
Browser bundle is tightValibot
Heavy invalid-input trafficValibot (faster fail path here)
Need the Zod ecosystem (resolvers, partners)Zod
Auditing unused deps after a swapPair with knip vs depcheck​
Comparing test runners beside schema testsSee Jest vs Vitest​

Bottom line: on 50k parses of one user object, Zod 4.6.5 hit 1.14M ops/s median while Valibot 1.5.0 hit 0.97M, but Valibot shipped a 15 KB gzip bundle against Zod’s 93 KB. Who should not switch: teams whose Zod schemas and partner libs already pass CI.

How this was made: I installed zod and valibot on the ShopperCove box, timed interleaved parse rounds after a warm-up, measured esbuild minify+gzip sizes, recorded JSON; the write-up was drafted with AI help and checked against that output.

Sources

  • https://zod.dev/
  • https://www.npmjs.com/package/zod
  • https://valibot.dev/
  • https://www.npmjs.com/package/valibot
  • https://github.com/colinhacks/zod
  • https://github.com/fabian-hiller/valibot

Related

  • https://www.shoppercove.com/blog/biome-vs-eslint-prettier
  • https://www.shoppercove.com/blog/oxlint-vs-eslint
  • https://www.shoppercove.com/blog/size-limit-vs-bundlesize
  • https://www.shoppercove.com/blog/knip-vs-depcheck
  • https://www.shoppercove.com/blog/jest-vs-vitest
  • https://www.shoppercove.com/blog/dprint-vs-prettier
  • https://www.shoppercove.com/blog/bun-test-vs-vitest
  • https://www.shoppercove.com/blog/esbuild-register-vs-jiti
zodvalibotbenchmarkingperformanceschema validationbundle sizejavascript

Lab evidence

What I found running this

Hands-on on ShopperCove box 6 Oct 2026 ~00:30–00:35 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). zod 4.6.5 vs valibot 1.5.0. Fixture /workspace/bench-zod-valibot/: one object schema (uuid, email, int age 0–120, tags[], nested profile, enum role); good + bad payloads. 2,000 warm iterations then 9 rounds × 50,000. Medians: zod.parse ok 1,144,494 ops/s (43.7 ms/50k); valibot.parse ok 968,187 (51.6 ms); zod.safeParse ok 1,139,141; valibot.safeParse ok 979,417; zod.safeParse fail 415,523; valibot.safeParse fail 697,760. Disk trees ~6.1 MB zod vs ~1.9 MB valibot. esbuild minify ESM: 452,999 B vs 85,126 B; gzip -9 92,636 B vs 15,422 B. Raw: /workspace/bench-zod-valibot/res-zod-valibot.json + res-bundle.json. Not tested: Ajv, async pipes, TS compile time, Deno/Bun, edge, schema codegen. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 09

    ohash vs object-hash: 10x Faster, 3.3 KB vs 11 KB

    5 Oct 2026

  • Plate 55

    Klona vs structuredClone: 1.4M vs 225k Clones per Second

    5 Oct 2026

  • Plate 38

    smol-toml vs @iarna/toml: 3x Faster on Deno Cargo

    5 Oct 2026

On this page

  1. What I tested
  2. How wide was the parse gap?
  3. Does the bundle gap change the call?
  4. Should you switch schema libraries?
  5. Sources
  6. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove