Benchmarks
Median results from interleaved rounds. Compare within each runtime; absolute rates vary by runner.
Full-stack SSR - Nifra vs the meta-frameworks
2026-11-10 · GitHub Actions accuracy run #42798158115; SSR payloads rebuilt from Nifra 5.13.0 · Node: ubuntu-26.04 · AMD EPYC 9V74 80-Core Processor · 4 vCPU; Bun: ubuntu-26.04 · AMD EPYC 7763 64-Core Processor · 4 vCPU · Bun 1.4.4, Node 26.13.0, Deno 2.9.7 · oha 1.16.0 · 50 connections
Each framework has uncached SSR and cached SSG/ISR rows. Compare Nifra's Node app with the Node meta-frameworks; multipliers use the uncached rows.
Next.js and all dynamic SSR rows are measured uncompressed (accept-encoding: identity) for like-for-like throughput.
Nifra also projects and validates loaderOutput for the client; comparator rows have no equivalent output boundary.
The static-host row is a plain Bun file server; no Nifra code runs per request.
React
A · Dynamic SSR
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + React (Node)v5.13.0 | 15,260 | 3.11 ms | 6.23 ms | 91.4 KB |
| Nifra + React (Bun)v5.13.0 | 13,846 | 3.44 ms | 7.00 ms | 91.4 KB |
| Remix / React Router (Node)v8.5.1 | 1,894 | 25.97 ms | 49.13 ms | 107.1 KB |
| Next.js (Node)v16.4.6 | 839 | 57.37 ms | 105.50 ms | 172 KB |
B · Cached SSG/ISR (cache warmed before measurement)
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + React SSG (Bun)v5.13.0 | 60,447 | 0.78 ms | 1.65 ms | 91.7 KB |
| Nifra + React ISR (Bun)v5.13.0 | 48,206 | 0.97 ms | 2.14 ms | 91.4 KB |
| Nifra + React SSG (Node)v5.13.0 | 32,116 | 1.48 ms | 2.97 ms | 91.7 KB |
| Nifra + React ISR (Node)v5.13.0 | 20,669 | 2.26 ms | 4.52 ms | 91.4 KB |
| Nifra + React SSG files on a static hostv5.13.0 | 18,205 | 2.71 ms | 3.17 ms | 91.7 KB |
| Next.js ISR (Node)v16.4.6 | 3,767 | 12.51 ms | 27.54 ms | 172 KB |
| Next.js static (Node)v16.4.6 | 3,761 | 12.53 ms | 26.33 ms | 172 KB |
Solid
A · Dynamic SSR
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + Solid (Node)v5.13.0 | 15,077 | 2.91 ms | 6.76 ms | 22.6 KB |
| Nifra + Solid (Bun)v5.13.0 | 13,970 | 3.49 ms | 5.93 ms | 22.6 KB |
| SolidStart (Node)v2.2.2 | 5,399 | 6.43 ms | 27.68 ms | 14.5 KB |
B · Cached SSG/ISR (cache warmed before measurement)
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + Solid SSG (Bun)v5.13.0 | 59,119 | 0.80 ms | 1.68 ms | 22.9 KB |
| Nifra + Solid SSG (Node)v5.13.0 | 31,762 | 1.50 ms | 3.01 ms | 22.9 KB |
| SolidStart static (Node)v2.2.2 | 22,212 | 2.21 ms | 3.55 ms | 14 KB |
| Nifra + Solid SSG files on a static hostv5.13.0 | 18,290 | 2.70 ms | 3.08 ms | 22.9 KB |
Vue
A · Dynamic SSR
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + Vue (Bun)v5.13.0 | 12,780 | 3.68 ms | 7.77 ms | 26 KB |
| Nifra + Vue (Node)v5.13.0 | 11,386 | 3.71 ms | 10.47 ms | 26 KB |
| Nuxt (Node)v4.6.4 | 1,371 | 35.73 ms | 69.95 ms | 75.9 KB |
B · Cached SSG/ISR (cache warmed before measurement)
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + Vue SSG (Bun)v5.13.0 | 58,700 | 0.78 ms | 1.88 ms | 26.4 KB |
| Nifra + Vue SSG (Node)v5.13.0 | 32,574 | 1.47 ms | 2.94 ms | 26.4 KB |
| Nifra + Vue SSG files on a static hostv5.13.0 | 18,417 | 2.68 ms | 3.08 ms | 26.4 KB |
| Nuxt static (Node)v4.6.4 | 17,153 | 2.73 ms | 4.85 ms | 70.4 KB |
Svelte
A · Dynamic SSR
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + Svelte (Node)v5.13.0 | 19,464 | 2.45 ms | 4.86 ms | 23.2 KB |
| Nifra + Svelte (Bun)v5.13.0 | 18,115 | 2.55 ms | 5.44 ms | 23.2 KB |
| SvelteKit (Node)v3.2.0 | 3,651 | 12.32 ms | 27.85 ms | 33 KB |
B · Cached SSG/ISR (cache warmed before measurement)
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + Svelte SSG (Bun)v5.13.0 | 60,663 | 0.78 ms | 1.66 ms | 23.5 KB |
| Nifra + Svelte SSG (Node)v5.13.0 | 32,229 | 1.48 ms | 2.96 ms | 23.5 KB |
| Nifra + Svelte SSG files on a static hostv5.13.0 | 18,524 | 2.67 ms | 3.03 ms | 23.5 KB |
| SvelteKit static (Node)v3.2.0 | 12,107 | 3.51 ms | 11.10 ms | 33.2 KB |
Preact
A · Dynamic SSR
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Raw Preact render (Node, ceiling)v6.8.2 | 31,301 | 1.52 ms | 3.05 ms | 4.7 KB |
| Nifra + Preact (Node)v5.13.0 | 17,561 | 2.58 ms | 6.37 ms | 25.4 KB |
| Nifra + Preact (Bun)v5.13.0 | 15,693 | 3.21 ms | 6.15 ms | 25.4 KB |
B · Cached SSG/ISR (cache warmed before measurement)
| Target | Median req/s | p50 | p99 | client JS (gz) |
|---|---|---|---|---|
| Nifra + Preact SSG (Bun)v5.13.0 | 60,846 | 0.77 ms | 1.63 ms | 25.8 KB |
| Nifra + Preact SSG (Node)v5.13.0 | 32,469 | 1.47 ms | 2.94 ms | 25.8 KB |
| Nifra + Preact SSG files on a static hostv5.13.0 | 18,456 | 2.68 ms | 3.04 ms | 25.8 KB |
n/a means client JS could not be measured from the HTML.Backend - HTTP throughput across runtimes
2026-11-10 · GitHub Actions accuracy run #42798158115 · Node: ubuntu-26.04 · Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz · 4 vCPU; Bun: ubuntu-26.04 · Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz · 4 vCPU; Deno: ubuntu-26.04 · Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz · 4 vCPU · Bun 1.4.4, Node 26.13.0, Deno 2.9.7 · oha 1.16.0 · 50 connections
Four workloads, ranked by their geometric mean.
Fastify on Bun/Deno uses node:http compatibility, not native ingress.
Bun 1.4.4
| Framework | GET / | GET /users/:id | GET /search?query | POST /users |
|---|---|---|---|---|
| Nifrav5.13.0 | 131,092 | 125,850 | 113,360 | 75,104 |
| Elysiav1.4.30 | 129,046 | 126,802 | 113,146 | 72,925 |
| Honov4.13.13 | 109,421 | 101,681 | 69,716 | 59,738 |
| Fastifyv5.12.7 | 63,360 | 61,838 | 57,130 | 43,973 |
Node 26.13.0
| Framework | GET / | GET /users/:id | GET /search?query | POST /users |
|---|---|---|---|---|
| Nifrav5.13.0 | 59,978 | 57,959 | 55,917 | 37,525 |
| Fastifyv5.12.7 | 56,663 | 53,287 | 52,001 | 35,774 |
| Honov4.13.13 | 53,326 | 50,334 | 37,737 | 29,549 |
| Elysiav1.4.30 | 41,839 | 39,539 | 39,033 | 20,414 |
| Expressv5.3.0 | 26,988 | 26,238 | 25,895 | 18,420 |
Deno 2.9.7
| Framework | GET / | GET /users/:id | GET /search?query | POST /users |
|---|---|---|---|---|
| Nifrav5.13.0 | 125,564 | 119,295 | 109,838 | 72,996 |
| Elysiav1.4.30 | 112,508 | 102,250 | 102,467 | 51,134 |
| Honov4.13.13 | 120,566 | 111,000 | 69,030 | 63,406 |
| Fastifyv5.12.7 | 41,550 | 39,974 | 39,236 | 35,804 |
Backend - the same routes with a real route's work
2026-11-10 · GitHub Actions accuracy run #42798158115 · Node: ubuntu-26.04 · Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz · 4 vCPU; Bun: ubuntu-26.04 · Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz · 4 vCPU; Deno: ubuntu-26.04 · Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz · 4 vCPU · Bun 1.4.4, Node 26.13.0, Deno 2.9.7 · oha 1.16.0 · 50 connections
The same routes with security headers, CORS, request ID, bearer auth, and cookie handling.
Allowed-origin GET/POST only; CORS preflight and rejected origins are excluded.
Bun 1.4.4
| Framework | GET /api/orders | POST /api/orders | GET + body hash |
|---|---|---|---|
| Nifrav5.13.0 | 58,769 | 51,717 | 43,513 |
| Elysiav1.4.30 | 49,686 | 43,497 | 35,308 |
| Honov4.13.13 | 43,091 | 41,601 | 28,308 |
| Fastifyv5.12.7 | 38,769 | 32,340 | 35,210 |
Node 26.13.0
| Framework | GET /api/orders | POST /api/orders | GET + body hash |
|---|---|---|---|
| Nifrav5.13.0 | 37,712 | 30,573 | 33,016 |
| Fastifyv5.12.7 | 35,951 | 28,928 | 32,868 |
| Expressv5.3.0 | 18,725 | 16,059 | 18,567 |
| Elysiav1.4.30 | 20,863 | 14,676 | 12,894 |
| Honov4.13.13 | 20,494 | 19,029 | 9,823 |
Deno 2.9.7
| Framework | GET /api/orders | POST /api/orders | GET + body hash |
|---|---|---|---|
| Nifrav5.13.0 | 36,676 | 39,384 | 28,807 |
| Fastifyv5.12.7 | 27,034 | 27,708 | 25,090 |
| Elysiav1.4.30 | 28,137 | 25,153 | 19,323 |
| Honov4.13.13 | 27,667 | 31,253 | 12,474 |
Backend - memory footprint across runtimes
RSS is process-wide after GC; POST heap is retained JavaScript memory.
Median of 5 fresh processes · 50k GETs + POSTs per process · 50 connections · sorted by after-POST RSS; Low marks each column's minimum.
Node 26.13.0
2026-11-10 · Capture run · AMD EPYC 9V45 96-Core Processor
| Framework | Ready RSS | After GET | After POST | Peak RSS | POST heap |
|---|---|---|---|---|---|
| Nifrav5.13.0 | 99.5 MiB | 120.9 MiB | 121.6 MiBLow | 121.6 MiBLow | 15.0 MiB |
| Honov4.13.13 | 96.8 MiBLow | 116.3 MiBLow | 124.3 MiB | 124.3 MiB | 12.9 MiBLow |
| Fastifyv5.12.7 | 106.3 MiB | 125.3 MiB | 126.5 MiB | 126.5 MiB | 16.9 MiB |
| Expressv5.3.0 | 102.0 MiB | 124.4 MiB | 127.7 MiB | 127.7 MiB | 15.0 MiB |
| Elysiav1.4.30 | 104.0 MiB | 124.6 MiB | 207.1 MiB | 207.1 MiB | 16.7 MiB |
Bun 1.4.4
2026-11-10 · Capture run · AMD EPYC 9V45 96-Core Processor
| Framework | Ready RSS | After GET | After POST | Peak RSS | POST heap |
|---|---|---|---|---|---|
| Honov4.13.13 | 35.8 MiBLow | 47.1 MiBLow | 49.0 MiBLow | 60.0 MiB | 1.6 MiBLow |
| Nifrav5.13.0 | 37.3 MiB | 47.8 MiB | 50.0 MiB | 57.1 MiBLow | 1.9 MiB |
| Elysiav1.4.30 | 45.9 MiB | 51.3 MiB | 53.5 MiB | 64.9 MiB | 3.0 MiB |
| Expressv5.3.0 | 52.5 MiB | 69.6 MiB | 74.3 MiB | 88.3 MiB | 5.7 MiB |
| Fastifyv5.12.7 | 62.2 MiB | 76.2 MiB | 80.1 MiB | 90.5 MiB | 8.1 MiB |
Deno 2.9.7
2026-11-10 · Capture run · AMD EPYC 9V45 96-Core Processor
| Framework | Ready RSS | After GET | After POST | Peak RSS | POST heap |
|---|---|---|---|---|---|
| Nifrav5.13.0 | 57.9 MiB | 72.3 MiBLow | 74.0 MiBLow | 73.8 MiBLow | 6.8 MiB |
| Honov4.13.13 | 57.5 MiBLow | 76.3 MiB | 77.2 MiB | 77.3 MiB | 6.7 MiBLow |
| Elysiav1.4.30 | 66.3 MiB | 81.0 MiB | 136.4 MiB | 136.1 MiB | 10.3 MiB |
| Expressv5.3.0 | 70.6 MiB | 167.5 MiB | 174.1 MiB | 175.6 MiB | 9.9 MiB |
| Fastifyv5.12.7 | 76.6 MiB | 170.7 MiB | 177.7 MiB | 177.4 MiB | 11.8 MiB |