DEV Community

reactuse.com
reactuse.com

Posted on • Originally published at paretojs.tech

We Benchmarked Our SSR Framework Against Next.js — Here's What We Found

We built Pareto, a lightweight streaming-first React SSR framework on Vite. Claims are cheap — so we built an automated benchmark suite that runs in CI on every PR, comparing Pareto against Next.js, React Router (Remix), and TanStack Start on identical hardware.

What We Tested

Four scenarios covering the most common SSR workloads:

  • Static SSR — Page with inline data, no async loader. Pure SSR throughput.
  • Data Loading — Loader with simulated 10ms DB query. SSR + data fetching overhead.
  • Streaming SSRdefer() + Suspense with 200ms delayed data. Streaming pipeline efficiency.
  • API / JSON — Pure JSON endpoint. Routing + serialization overhead.

All benchmarks on GitHub Actions (Ubuntu, Node 22, 4 CPUs), using autocannon with 100 connections for 30 seconds.

Throughput: Requests Per Second

Scenario Pareto Next.js React Router TanStack Start
Static SSR 2,224/s 3,328/s 997/s 2,009/s
Data Loading 2,733/s 293/s 955/s 1,386/s
Streaming SSR 247/s 236/s 247/s 247/s
API / JSON 3,675/s 2,212/s 1,950/s

Next.js wins on static SSR. But the moment a loader is involved, Pareto handles 9.3x more requests than Next.js and 2.9x more than React Router.

Load Capacity: Max Sustainable QPS

We ran a ramp-up test from 1 to 1,000 concurrent connections, measuring the max QPS each framework sustains while keeping p99 latency under 500ms.

Scenario Pareto Next.js React Router TanStack Start
Static SSR 2,281/s 2,203/s 1,098/s 1,515/s
Data Loading 2,735/s 331/s 1,044/s 1,458/s
Streaming SSR 2,022/s 310/s 807/s 960/s
API / JSON 3,556/s 1,419/s 1,912/s

Under streaming SSR load, Pareto sustains 2,022 req/s — that's 6.5x Next.js and 2.5x React Router.

What this looks like in practice: Say your product page needs to serve 2,000 req/s at peak. With Pareto, that's a single server. With Next.js at 331/s, you'd need 6 servers behind a load balancer. For streaming SSR dashboards, it's 1 Pareto instance vs 7 Next.js instances.

Latency

Scenario Pareto p50/p99 Next.js p50/p99 React Router p50/p99
Static SSR 431ms / 1.35s 244ms / 326ms 704ms / 7.16s
Data Loading 350ms / 702ms 1.42s / 7.82s 760ms / 7.41s
API / JSON 266ms / 320ms 283ms / 321ms 486ms / 2.12s

Under 100 concurrent connections, Pareto's data loading p99 is 702ms while Next.js spikes to 7.82s. 99% of users get their page in under 700ms with Pareto. With Next.js, 1 in 100 users waits nearly 8 seconds.

Bundle Size

Framework Client JS (gzip) Total (gzip)
Pareto 62 KB 72 KB
Next.js 233 KB 409 KB
React Router 100 KB 102 KB
TanStack Start 101 KB 272 KB

62 KB of client JavaScript — roughly 1/4 of Next.js. On 4G mobile (~5 Mbps), that's 100ms to download vs 370ms. On 3G, it's 330ms vs 1.2 seconds before any rendering begins.

The Cost Difference

Here's a concrete scenario — a SaaS dashboard at 10,000 data-loading req/s peak:

Framework Servers needed (4 CPU) Monthly cost (est.)
Pareto 4 ~$160
TanStack Start 7 ~$280
React Router 10 ~$400
Next.js 31 ~$1,240

How We Keep Benchmarks Honest

  • CI automated — runs on every PR touching core code
  • System tuning — ASLR disabled, CPU governor performance
  • Median aggregation — eliminates outlier noise, CV% for stability
  • Sequential isolation — one framework at a time, cooldown between runs
  • Same hardware — all frameworks on the same GitHub Actions runner

The full suite is open source: github.com/childrentime/pareto/tree/main/benchmarks

npx create-pareto my-app
cd my-app && npm install && npm run dev
Enter fullscreen mode Exit fullscreen mode

Pareto is a lightweight, streaming-first React SSR framework built on Vite. GitHub · Docs

Top comments (0)