Kanon Performance Benchmarks
Real-world validation benchmarks. Data auto-generated on Jan 31, 2026.
TL;DR
Kanon JIT dominates on discriminated unions and complex schemas. TypeBox/AJV win on simple validations. For typical API/form validation, Kanon is 2-3x faster than Zod/Valibot.
Operations per second. Higher is better.
Methodology
Each benchmark:
- Creates a pool of 10,000 test objects
- Runs validation in a tight loop
- Measures operations per second with statistical analysis
- Reports min, max, mean, percentiles (p75, p99, p995, p999)
- Includes relative margin of error (rme) for confidence
The "fastest" label is only awarded when the winner is ≥10% faster than the runner-up. Otherwise, it's considered a statistical tie.
Does Performance Matter?
Not all validations matter equally for performance. Validating an API response called 1000x/sec matters more than a one-time config check. We assign weights based on real-world usage patterns:
| Perf matters? | Weight | Description | Examples |
|---|---|---|---|
CRITICAL A lot | 5 pts | Hot path functions called in tight loops | map, filter, reduce, groupBy, chunk |
HIGH Yes | 3 pts | Frequently used utilities, but not in tight loops | get, set, pick, omit, cloneDeep |
MEDIUM A bit | 1 pt | Occasional utilities | Type guards (isArray, isString), string formatting |
LOW No | 0.5 pts | Setup-only functions where runtime perf is irrelevant | debounce, throttle, once, memoize |
This scoring gives a more realistic picture of which library will actually make your app faster.
Libraries Tested
| Library | Version | Description |
|---|---|---|
| @sinclair/typebox | 0.34.47 | JSON Schema with TypeScript inference + JIT |
| ajv | 8.17.1 | JSON Schema validator with JIT compilation |
| fastest-validator | 1.19.1 | High-performance validator with JIT |
| kanon | 1.1.0 | Pithos validation module (schema-first + JIT) |
| superstruct | 2.0.2 | Composable validation with custom types |
| valibot | 1.2.0 | Modular schema validation, tree-shakable |
| zod | 4.3.5 | Schema-first validation with TypeScript inference |
Benchmark Results
| Test | @kanon/V3.0 | @kanon/JIT | AJV | Fast-Validator | Superstruct | TypeBox | Valibot | Zod |
|---|---|---|---|---|---|---|---|---|
| Critical | ||||||||
Login Form Validation CRITICAL | 5 pts | 7.47M ops/s (2.04x) | 9.83M ops/s (1.55x) | 8.64M ops/s (1.76x) | 9.96M ops/s (1.53x) | 596.04K ops/s (25.54x) | 15.22M ops/s fastest | 3.33M ops/s (4.57x) | 4.91M ops/s (3.1x) |
Payment Form (conditional validation) CRITICAL | 5 pts | 5.68M ops/s (3.15x) | 17.91M ops/s fastest | 15.38M ops/s (1.16x) | 12.02M ops/s (1.49x) | 285.12K ops/s (62.8x) | 1.70M ops/s (10.5x) | 1.69M ops/s (10.58x) | 2.63M ops/s (6.82x) |
User Registration (with password confirm) CRITICAL | 5 pts | 5.13M ops/s (1.71x) | 5.93M ops/s (1.48x) | 6.74M ops/s (1.3x) | 6.81M ops/s (1.29x) | 297.83K ops/s (29.46x) | 8.77M ops/s fastest | 1.64M ops/s (5.36x) | 2.04M ops/s (4.31x) |
| High | ||||||||
API Response (discriminated union) HIGH | 3 pts | 8.26M ops/s (3.45x) | 28.51M ops/s fastest | 17.82M ops/s (1.6x) | 14.45M ops/s (1.97x) | 373.72K ops/s (76.29x) | 3.35M ops/s (8.51x) | 2.41M ops/s (11.81x) | 8.18M ops/s (3.48x) |
Blog Post with Comments HIGH | 3 pts | 2.57M ops/s (2.38x) | 6.10M ops/s fastest | 4.91M ops/s (1.24x) | 3.41M ops/s (1.79x) | 108.24K ops/s (56.32x) | 1.48M ops/s (4.12x) | 767.56K ops/s (7.94x) | 1.50M ops/s (4.07x) |
E-commerce Product HIGH | 3 pts | 4.93M ops/s (2.75x) | 13.57M ops/s fastest | 12.30M ops/s (1.1x) | 11.84M ops/s (1.15x) | 194.48K ops/s (69.79x) | 1.12M ops/s (12.07x) | 1.38M ops/s (9.82x) | 2.65M ops/s (5.13x) |
Event Booking HIGH | 3 pts | 1.50M ops/s (5.69x) | 8.55M ops/s fastest | 3.60M ops/s (2.38x) | 2.80M ops/s (3.05x) | 113.39K ops/s (75.41x) | 2.06M ops/s (4.15x) | 678.20K ops/s (12.61x) | 812.84K ops/s (10.52x) |
Invalid Login (error handling) HIGH | 3 pts | 5.57M ops/s (1.67x) | 8.81M ops/s (1.06x) | 9.32M ops/s fastest | 1.98M ops/s (4.71x) | 235.84K ops/s (39.5x) | 7.76M ops/s (1.2x) | 2.15M ops/s (4.34x) | 142.30K ops/s (65.46x) |
| Medium | ||||||||
Search Params (with coercion) MEDIUM | 1 pts | 4.27M ops/s (5.61x) | 23.95M ops/s fastest | 22.18M ops/s (1.08x) | 17.43M ops/s (1.37x) | 188.97K ops/s (126.74x) | 1.95M ops/s (12.27x) | 1.77M ops/s (13.51x) | 4.38M ops/s (5.47x) |
User Profile Update (optional fields) MEDIUM | 1 pts | 5.98M ops/s (3.21x) | 19.21M ops/s fastest | 7.80M ops/s (2.46x) | 11.33M ops/s (1.7x) | 425.89K ops/s (45.1x) | 5.25M ops/s (3.66x) | 2.30M ops/s (8.34x) | 2.60M ops/s (7.4x) |
📊 Performance Summary
@kanon/JIT
TypeBox
AJV📈 Weighted Summary
🏆 @kanon/JIT dominates real-world scenarios!
@kanon/JIT
TypeBox
AJVOn critical + high priority tasks, @kanon/JIT is 2.4x ahead.
Detailed Statistics
For the skeptics who want to see the raw numbers:
Login Form ValidationCRITICAL
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| TypeBox 🏆 | 15.22M | 0.0000 | 0.0197 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.07% | 7,611,730 |
| Fast-Validator | 9.96M | 0.0000 | 0.0242 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.07% | 4,979,899 |
| @kanon/JIT | 9.83M | 0.0000 | 0.0275 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.06% | 4,914,072 |
| AJV | 8.64M | 0.0000 | 0.4407 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | 0.0002 | ±0.19% | 4,318,839 |
| @kanon/V3.0 | 7.47M | 0.0000 | 0.0267 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | 0.0003 | ±0.06% | 3,732,849 |
| Zod | 4.91M | 0.0001 | 0.2380 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0004 | ±0.21% | 2,453,001 |
| Valibot | 3.33M | 0.0002 | 0.3037 | 0.0003 | 0.0003 | 0.0004 | 0.0004 | 0.0005 | ±0.27% | 1,665,585 |
| Superstruct | 596.04K | 0.0014 | 0.2955 | 0.0017 | 0.0016 | 0.0021 | 0.0022 | 0.0085 | ±0.58% | 298,023 |
User Registration (with password confirm)CRITICAL
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| TypeBox 🏆 | 8.77M | 0.0000 | 0.5107 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | 0.0003 | ±0.68% | 4,387,058 |
| Fast-Validator | 6.81M | 0.0000 | 0.7060 | 0.0001 | 0.0002 | 0.0002 | 0.0002 | 0.0004 | ±0.57% | 3,405,163 |
| AJV | 6.74M | 0.0000 | 0.3164 | 0.0001 | 0.0002 | 0.0002 | 0.0002 | 0.0003 | ±0.14% | 3,369,058 |
| @kanon/JIT | 5.93M | 0.0000 | 0.0274 | 0.0002 | 0.0002 | 0.0002 | 0.0002 | 0.0003 | ±0.06% | 2,964,740 |
| @kanon/V3.0 | 5.13M | 0.0001 | 0.0274 | 0.0002 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | ±0.08% | 2,564,632 |
| Zod | 2.04M | 0.0003 | 0.5549 | 0.0005 | 0.0005 | 0.0006 | 0.0007 | 0.0011 | ±0.52% | 1,018,048 |
| Valibot | 1.64M | 0.0005 | 0.3863 | 0.0006 | 0.0006 | 0.0008 | 0.0008 | 0.0010 | ±0.21% | 818,343 |
| Superstruct | 297.83K | 0.0030 | 0.3087 | 0.0034 | 0.0033 | 0.0040 | 0.0048 | 0.0157 | ±0.55% | 148,916 |
API Response (discriminated union)HIGH
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| @kanon/JIT 🏆 | 28.51M | 0.0000 | 0.0410 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0001 | ±0.08% | 14,254,971 |
| AJV | 17.82M | 0.0000 | 0.3953 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.52% | 8,908,332 |
| Fast-Validator | 14.45M | 0.0000 | 0.0324 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | ±0.06% | 7,225,420 |
| @kanon/V3.0 | 8.26M | 0.0000 | 0.0585 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | 0.0002 | ±0.09% | 4,131,690 |
| Zod | 8.18M | 0.0000 | 0.2304 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | 0.0003 | ±0.26% | 4,091,166 |
| TypeBox | 3.35M | 0.0002 | 0.3292 | 0.0003 | 0.0003 | 0.0004 | 0.0004 | 0.0005 | ±0.24% | 1,675,506 |
| Valibot | 2.41M | 0.0002 | 0.9493 | 0.0004 | 0.0005 | 0.0005 | 0.0006 | 0.0011 | ±0.51% | 1,206,584 |
| Superstruct | 373.72K | 0.0019 | 0.2455 | 0.0027 | 0.0035 | 0.0039 | 0.0042 | 0.0099 | ±0.45% | 186,858 |
E-commerce ProductHIGH
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| @kanon/JIT 🏆 | 13.57M | 0.0000 | 0.0597 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.09% | 6,786,147 |
| AJV | 12.30M | 0.0000 | 0.6468 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.34% | 6,152,443 |
| Fast-Validator | 11.84M | 0.0000 | 0.5260 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.49% | 5,921,945 |
| @kanon/V3.0 | 4.93M | 0.0001 | 0.0225 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0004 | ±0.07% | 2,465,677 |
| Zod | 2.65M | 0.0002 | 0.3921 | 0.0004 | 0.0004 | 0.0005 | 0.0006 | 0.0007 | ±0.50% | 1,323,052 |
| Valibot | 1.38M | 0.0006 | 0.3756 | 0.0007 | 0.0008 | 0.0009 | 0.0010 | 0.0011 | ±0.36% | 691,078 |
| TypeBox | 1.12M | 0.0007 | 0.4892 | 0.0009 | 0.0010 | 0.0011 | 0.0012 | 0.0045 | ±0.35% | 562,330 |
| Superstruct | 194.48K | 0.0043 | 0.2581 | 0.0051 | 0.0054 | 0.0061 | 0.0066 | 0.0150 | ±0.51% | 97,242 |
Blog Post with CommentsHIGH
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| @kanon/JIT 🏆 | 6.10M | 0.0000 | 0.1039 | 0.0002 | 0.0002 | 0.0002 | 0.0002 | 0.0003 | ±0.11% | 3,047,916 |
| AJV | 4.91M | 0.0001 | 0.6354 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0005 | ±0.28% | 2,457,042 |
| Fast-Validator | 3.41M | 0.0001 | 0.3540 | 0.0003 | 0.0003 | 0.0005 | 0.0006 | 0.0027 | ±0.25% | 1,707,302 |
| @kanon/V3.0 | 2.57M | 0.0002 | 0.0383 | 0.0004 | 0.0005 | 0.0005 | 0.0005 | 0.0007 | ±0.08% | 1,283,142 |
| Zod | 1.50M | 0.0004 | 0.3613 | 0.0007 | 0.0007 | 0.0009 | 0.0010 | 0.0011 | ±0.43% | 748,702 |
| TypeBox | 1.48M | 0.0005 | 0.4840 | 0.0007 | 0.0007 | 0.0008 | 0.0008 | 0.0012 | ±0.38% | 738,933 |
| Valibot | 767.56K | 0.0007 | 0.2901 | 0.0013 | 0.0015 | 0.0018 | 0.0019 | 0.0023 | ±0.32% | 383,779 |
| Superstruct | 108.24K | 0.0053 | 0.2312 | 0.0092 | 0.0108 | 0.0133 | 0.0157 | 0.0365 | ±0.52% | 54,122 |
Search Params (with coercion)MEDIUM
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| @kanon/JIT 🏆 | 23.95M | 0.0000 | 0.1336 | 0.0000 | 0.0000 | 0.0001 | 0.0001 | 0.0001 | ±0.10% | 11,975,044 |
| AJV | 22.18M | 0.0000 | 0.0799 | 0.0000 | 0.0000 | 0.0001 | 0.0001 | 0.0001 | ±0.11% | 11,089,245 |
| Fast-Validator | 17.43M | 0.0000 | 0.0445 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.08% | 8,712,950 |
| Zod | 4.38M | 0.0001 | 0.3579 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0005 | ±0.47% | 2,188,594 |
| @kanon/V3.0 | 4.27M | 0.0001 | 5.0260 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0004 | ±7.22% | 2,135,965 |
| TypeBox | 1.95M | 0.0004 | 0.5476 | 0.0005 | 0.0005 | 0.0006 | 0.0007 | 0.0009 | ±0.34% | 975,622 |
| Valibot | 1.77M | 0.0004 | 0.7592 | 0.0006 | 0.0005 | 0.0007 | 0.0009 | 0.0044 | ±0.55% | 886,359 |
| Superstruct | 188.97K | 0.0048 | 3.6418 | 0.0053 | 0.0052 | 0.0076 | 0.0089 | 0.0157 | ±1.58% | 94,487 |
User Profile Update (optional fields)MEDIUM
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| @kanon/JIT 🏆 | 19.21M | 0.0000 | 0.4785 | 0.0001 | 0.0000 | 0.0001 | 0.0001 | 0.0002 | ±0.26% | 9,604,854 |
| Fast-Validator | 11.33M | 0.0000 | 0.0463 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.09% | 5,664,294 |
| AJV | 7.80M | 0.0000 | 0.4540 | 0.0001 | 0.0002 | 0.0003 | 0.0003 | 0.0004 | ±0.21% | 3,899,045 |
| @kanon/V3.0 | 5.98M | 0.0000 | 0.0862 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0004 | ±0.11% | 2,989,174 |
| TypeBox | 5.25M | 0.0000 | 0.4448 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0004 | ±0.44% | 2,623,700 |
| Zod | 2.60M | 0.0001 | 0.5583 | 0.0004 | 0.0005 | 0.0007 | 0.0007 | 0.0010 | ±0.52% | 1,298,461 |
| Valibot | 2.30M | 0.0002 | 0.3610 | 0.0004 | 0.0006 | 0.0008 | 0.0008 | 0.0010 | ±0.31% | 1,151,993 |
| Superstruct | 425.89K | 0.0015 | 1.8213 | 0.0023 | 0.0026 | 0.0045 | 0.0060 | 0.0112 | ±1.02% | 212,946 |
Payment Form (conditional validation)CRITICAL
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| @kanon/JIT 🏆 | 17.91M | 0.0000 | 0.6350 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | ±0.31% | 8,953,211 |
| AJV | 15.38M | 0.0000 | 0.7495 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.31% | 7,689,555 |
| Fast-Validator | 12.02M | 0.0000 | 0.5262 | 0.0001 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | ±0.61% | 6,009,955 |
| @kanon/V3.0 | 5.68M | 0.0000 | 0.0678 | 0.0002 | 0.0002 | 0.0003 | 0.0003 | 0.0003 | ±0.10% | 2,839,275 |
| Zod | 2.63M | 0.0002 | 0.8904 | 0.0004 | 0.0005 | 0.0005 | 0.0006 | 0.0036 | ±0.81% | 1,312,783 |
| TypeBox | 1.70M | 0.0005 | 0.3546 | 0.0006 | 0.0006 | 0.0007 | 0.0008 | 0.0012 | ±0.18% | 852,429 |
| Valibot | 1.69M | 0.0005 | 0.0426 | 0.0006 | 0.0006 | 0.0007 | 0.0007 | 0.0024 | ±0.09% | 846,324 |
| Superstruct | 285.12K | 0.0029 | 0.5393 | 0.0035 | 0.0035 | 0.0045 | 0.0072 | 0.0146 | ±0.64% | 142,558 |
Event BookingHIGH
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| @kanon/JIT 🏆 | 8.55M | 0.0000 | 0.0349 | 0.0001 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | ±0.07% | 4,275,359 |
| AJV | 3.60M | 0.0000 | 1.9146 | 0.0003 | 0.0003 | 0.0005 | 0.0005 | 0.0007 | ±1.64% | 1,799,473 |
| Fast-Validator | 2.80M | 0.0000 | 0.5001 | 0.0004 | 0.0004 | 0.0006 | 0.0007 | 0.0042 | ±0.65% | 1,401,667 |
| TypeBox | 2.06M | 0.0002 | 18.5485 | 0.0005 | 0.0004 | 0.0008 | 0.0010 | 0.0043 | ±10.22% | 1,031,067 |
| @kanon/V3.0 | 1.50M | 0.0002 | 4.2404 | 0.0007 | 0.0008 | 0.0013 | 0.0018 | 0.0070 | ±2.14% | 751,065 |
| Zod | 812.84K | 0.0004 | 0.6644 | 0.0012 | 0.0015 | 0.0038 | 0.0049 | 0.0107 | ±0.79% | 406,419 |
| Valibot | 678.20K | 0.0007 | 0.5315 | 0.0015 | 0.0018 | 0.0025 | 0.0050 | 0.0102 | ±0.58% | 339,102 |
| Superstruct | 113.39K | 0.0041 | 0.6500 | 0.0088 | 0.0106 | 0.0170 | 0.0211 | 0.0648 | ±0.89% | 56,694 |
Invalid Login (error handling)HIGH
| Library | ops/s | min | max | mean | p75 | p99 | p995 | p999 | rme | samples |
|---|---|---|---|---|---|---|---|---|---|---|
| AJV 🏆 | 9.32M | 0.0000 | 0.0513 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | 0.0002 | ±0.08% | 4,657,623 |
| @kanon/JIT | 8.81M | 0.0000 | 0.0338 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | 0.0002 | ±0.07% | 4,404,544 |
| TypeBox | 7.76M | 0.0000 | 0.4842 | 0.0001 | 0.0001 | 0.0002 | 0.0002 | 0.0003 | ±0.64% | 3,877,990 |
| @kanon/V3.0 | 5.57M | 0.0000 | 5.0055 | 0.0002 | 0.0002 | 0.0002 | 0.0002 | 0.0003 | ±2.51% | 2,785,167 |
| Valibot | 2.15M | 0.0002 | 0.4990 | 0.0005 | 0.0005 | 0.0007 | 0.0008 | 0.0037 | ±0.64% | 1,072,991 |
| Fast-Validator | 1.98M | 0.0000 | 0.3249 | 0.0005 | 0.0007 | 0.0012 | 0.0013 | 0.0015 | ±0.45% | 988,404 |
| Superstruct | 235.84K | 0.0017 | 0.4763 | 0.0042 | 0.0051 | 0.0069 | 0.0086 | 0.0119 | ±0.52% | 117,918 |
| Zod | 142.30K | 0.0002 | 5.7275 | 0.0070 | 0.0095 | 0.0135 | 0.0160 | 0.0255 | ±5.21% | 71,151 |
Why Kanon JIT is Fast
- JIT Compilation: Schemas are compiled to optimized JavaScript functions at runtime
- No runtime type checks: Types are validated at compile-time by TypeScript
- Minimal abstraction: Direct validation logic, no class hierarchies
- Discriminated unions: O(1) lookup instead of O(n) trial-and-error
A Note on Coercion Performance
On basic coercion operations, Kanon and Zod are roughly equivalent: each wins some benchmarks. This is despite a deliberate architectural difference.
Zod mutates the input directly:
// Zod's approach (simplified)
if (def.coerce) {
payload.value = new Date(payload.value); // mutation!
}
Kanon returns a new value:
// Kanon's approach
if (value instanceof Date) return true;
return { coerced: new Date(value) }; // pure, no mutation
We chose immutability over raw speed because:
- Predictability: Functions don't modify their arguments
- Debugging: Easier to trace where values come from
- Composition: Pure functions compose better
- Safety: No unexpected side-effects
The performance difference is negligible in practice (~0.00001ms per validation), and Kanon still dominates on coercion with constraints (36x faster than Zod on date.max()), which is the common real-world use case.
Reproduce These Results
Want to verify these results? See how to reproduce our data.
Related
- Kanon vs Zod — Full comparison: philosophy, API, migration
- Zygos — Performance — Result pattern benchmarks
- Kanon Module Guide — Full module documentation