Skip to content

Commit ff771ce

Browse files
childrentimeclaude
andcommitted
chore: add benchmark blog posts for external platforms
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a4c4ea5 commit ff771ce

4 files changed

Lines changed: 282 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
- For `create-pareto`, run `pnpm templates` before publishing to regenerate templates with resolved `workspace:*` and `catalog:` versions.
66
- Full command: `pnpm publish --access public --no-git-checks --registry https://registry.npmjs.org`
77

8+
## External Blog Posts
9+
10+
- Blog posts for external platforms (掘金, Medium, dev.to) live in `blog-external/`.
11+
- Naming convention: `{topic}-{platform}.md` (e.g. `benchmarks-devto.md`, `benchmarks-juejin.md`).
12+
- dev.to posts include frontmatter (`published`, `tags`, `canonical_url`). Medium and 掘金 are plain markdown.
13+
- Always set `canonical_url` to the paretojs.tech blog post to avoid SEO duplication.
14+
815
## Code Conventions
916

1017
- **No barrel files** — Do not create `index.ts` re-export files. Import directly from the source module (e.g. `from '../ndjson/reader'`, not `from '../ndjson'`). Barrel files add indirection without value.

blog-external/benchmarks-devto.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
title: "We Benchmarked Our SSR Framework Against Next.js — Here's What We Found"
3+
published: true
4+
tags: react, nextjs, performance, ssr
5+
series:
6+
canonical_url: https://paretojs.tech/blog/benchmarks/
7+
cover_image:
8+
---
9+
10+
We built [Pareto](https://github.com/childrentime/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.
11+
12+
## What We Tested
13+
14+
Four scenarios covering the most common SSR workloads:
15+
16+
- **Static SSR** — Page with inline data, no async loader. Pure SSR throughput.
17+
- **Data Loading** — Loader with simulated 10ms DB query. SSR + data fetching overhead.
18+
- **Streaming SSR**`defer()` + Suspense with 200ms delayed data. Streaming pipeline efficiency.
19+
- **API / JSON** — Pure JSON endpoint. Routing + serialization overhead.
20+
21+
All benchmarks on GitHub Actions (Ubuntu, Node 22, 4 CPUs), using [autocannon](https://github.com/mcollina/autocannon) with 100 connections for 30 seconds.
22+
23+
## Throughput: Requests Per Second
24+
25+
| Scenario | Pareto | Next.js | React Router | TanStack Start |
26+
|---|---:|---:|---:|---:|
27+
| Static SSR | 2,224/s | **3,328/s** | 997/s | 2,009/s |
28+
| Data Loading | **2,733/s** | 293/s | 955/s | 1,386/s |
29+
| Streaming SSR | **247/s** | 236/s | 247/s | 247/s |
30+
| API / JSON | **3,675/s** | 2,212/s | 1,950/s ||
31+
32+
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**.
33+
34+
## Load Capacity: Max Sustainable QPS
35+
36+
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.
37+
38+
| Scenario | Pareto | Next.js | React Router | TanStack Start |
39+
|---|---:|---:|---:|---:|
40+
| Static SSR | **2,281/s** | 2,203/s | 1,098/s | 1,515/s |
41+
| Data Loading | **2,735/s** | 331/s | 1,044/s | 1,458/s |
42+
| Streaming SSR | **2,022/s** | 310/s | 807/s | 960/s |
43+
| API / JSON | **3,556/s** | 1,419/s | 1,912/s ||
44+
45+
Under streaming SSR load, Pareto sustains **2,022 req/s** — that's **6.5x Next.js** and **2.5x React Router**.
46+
47+
**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**.
48+
49+
## Latency
50+
51+
| Scenario | Pareto p50/p99 | Next.js p50/p99 | React Router p50/p99 |
52+
|---|---:|---:|---:|
53+
| Static SSR | 431ms / 1.35s | **244ms / 326ms** | 704ms / 7.16s |
54+
| Data Loading | **350ms / 702ms** | 1.42s / 7.82s | 760ms / 7.41s |
55+
| API / JSON | **266ms / 320ms** | 283ms / 321ms | 486ms / 2.12s |
56+
57+
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.
58+
59+
## Bundle Size
60+
61+
| Framework | Client JS (gzip) | Total (gzip) |
62+
|---|---:|---:|
63+
| **Pareto** | **62 KB** | **72 KB** |
64+
| Next.js | 233 KB | 409 KB |
65+
| React Router | 100 KB | 102 KB |
66+
| TanStack Start | 101 KB | 272 KB |
67+
68+
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.
69+
70+
## The Cost Difference
71+
72+
Here's a concrete scenario — a SaaS dashboard at 10,000 data-loading req/s peak:
73+
74+
| Framework | Servers needed (4 CPU) | Monthly cost (est.) |
75+
|---|---:|---:|
76+
| **Pareto** | **4** | ~$160 |
77+
| TanStack Start | 7 | ~$280 |
78+
| React Router | 10 | ~$400 |
79+
| Next.js | 31 | ~$1,240 |
80+
81+
## How We Keep Benchmarks Honest
82+
83+
- **CI automated** — runs on every PR touching core code
84+
- **System tuning** — ASLR disabled, CPU governor `performance`
85+
- **Median aggregation** — eliminates outlier noise, CV% for stability
86+
- **Sequential isolation** — one framework at a time, cooldown between runs
87+
- **Same hardware** — all frameworks on the same GitHub Actions runner
88+
89+
The full suite is open source: [github.com/childrentime/pareto/tree/main/benchmarks](https://github.com/childrentime/pareto/tree/main/benchmarks)
90+
91+
```bash
92+
npx create-pareto my-app
93+
cd my-app && npm install && npm run dev
94+
```
95+
96+
---
97+
98+
*Pareto is a lightweight, streaming-first React SSR framework built on Vite. [GitHub](https://github.com/childrentime/pareto) · [Docs](https://paretojs.tech)*

blog-external/benchmarks-juejin.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# 我们把自己的 SSR 框架和 Next.js 做了全方位性能对比
2+
3+
我们做了 [Pareto](https://github.com/childrentime/pareto),一个基于 Vite 的轻量级流式 React SSR 框架。光说快不够——所以我们构建了一套自动化基准测试套件,在完全相同的硬件上将 Pareto 与 **Next.js****React Router (Remix)****TanStack Start** 进行了对比。测试在 CI 中自动运行,每个涉及核心代码的 PR 都会触发。
4+
5+
## 测试场景
6+
7+
四个覆盖最常见 SSR 工作负载的场景:
8+
9+
- **Static SSR** — 内联数据页面,无异步 loader。测量纯 SSR 吞吐量
10+
- **Data Loading** — 带 10ms 模拟数据库查询的 loader。测量 SSR + 数据获取开销
11+
- **Streaming SSR**`defer()` + Suspense,200ms 延迟数据。测量流式管道效率
12+
- **API / JSON** — 纯 JSON 端点。测量路由 + 序列化开销
13+
14+
所有测试在 GitHub Actions 上运行(Ubuntu, Node 22, 4 CPUs),使用 [autocannon](https://github.com/mcollina/autocannon),100 并发连接,每场景 30 秒。
15+
16+
## 吞吐量:每秒请求数
17+
18+
| 场景 | Pareto | Next.js | React Router | TanStack Start |
19+
|---|---:|---:|---:|---:|
20+
| Static SSR | 2,224/s | **3,328/s** | 997/s | 2,009/s |
21+
| Data Loading | **2,733/s** | 293/s | 955/s | 1,386/s |
22+
| Streaming SSR | **247/s** | 236/s | 247/s | 247/s |
23+
| API / JSON | **3,675/s** | 2,212/s | 1,950/s ||
24+
25+
Next.js 在静态 SSR 上表现最好。但一旦涉及 loader,Pareto 处理的请求量是 **Next.js 的 9.3 倍****React Router 的 2.9 倍**
26+
27+
## 单机负载能力:最大可持续 QPS
28+
29+
我们做了阶梯式压测,从 1 到 1,000 并发连接逐步增加,测量每个框架在 p99 延迟 < 500ms、错误率 < 1% 条件下的最大可持续 QPS。
30+
31+
| 场景 | Pareto | Next.js | React Router | TanStack Start |
32+
|---|---:|---:|---:|---:|
33+
| Static SSR | **2,281/s** | 2,203/s | 1,098/s | 1,515/s |
34+
| Data Loading | **2,735/s** | 331/s | 1,044/s | 1,458/s |
35+
| Streaming SSR | **2,022/s** | 310/s | 807/s | 960/s |
36+
| API / JSON | **3,556/s** | 1,419/s | 1,912/s ||
37+
38+
流式 SSR 下,Pareto 可持续 **2,022 req/s**——是 **Next.js 的 6.5 倍****React Router 的 2.5 倍**
39+
40+
**这意味着什么:** 假设你的产品页面高峰期需要每秒处理 2,000 个请求。用 Pareto,一台服务器就够了。Next.js 每个实例只能处理 331/s,你需要负载均衡后面挂 **6 台服务器**。对于流式 SSR 仪表板,同样的 2,000 req/s 需要 **1 台 Pareto** vs **7 台 Next.js**
41+
42+
这不只是基准测试数字——而是基础设施成本、部署复杂度和运维负担的直接缩减。
43+
44+
## 延迟
45+
46+
| 场景 | Pareto p50/p99 | Next.js p50/p99 | React Router p50/p99 |
47+
|---|---:|---:|---:|
48+
| Static SSR | 431ms / 1.35s | **244ms / 326ms** | 704ms / 7.16s |
49+
| Data Loading | **350ms / 702ms** | 1.42s / 7.82s | 760ms / 7.41s |
50+
| API / JSON | **266ms / 320ms** | 283ms / 321ms | 486ms / 2.12s |
51+
52+
在 100 并发连接下,Pareto 的数据加载 p99 是 **702ms**,Next.js 飙升到 **7.82s**。99% 的用户在 Pareto 下 700ms 内拿到数据页面;Next.js 在相同负载下,每 100 个用户中有 1 个要等将近 8 秒——足以关掉页面。
53+
54+
## 产物体积
55+
56+
| 框架 | 客户端 JS (gzip) | 总计 (gzip) |
57+
|---|---:|---:|
58+
| **Pareto** | **62 KB** | **72 KB** |
59+
| Next.js | 233 KB | 409 KB |
60+
| React Router | 100 KB | 102 KB |
61+
| TanStack Start | 101 KB | 272 KB |
62+
63+
62 KB gzip 后——约为 Next.js 的四分之一。在 4G 网络(~5 Mbps)下,下载时间 **100ms vs 370ms**。在 3G 网络下,**330ms vs 1.2 秒**——渲染还没开始。
64+
65+
## 服务器成本差异
66+
67+
一个 SaaS 仪表板,高峰期每秒 10,000 个数据加载请求:
68+
69+
| 框架 | 需要的服务器数(4 CPU) | 月费用(估算) |
70+
|---|---:|---:|
71+
| **Pareto** | **4 台** | ~$160 |
72+
| TanStack Start | 7 台 | ~$280 |
73+
| React Router | 10 台 | ~$400 |
74+
| Next.js | 31 台 | ~$1,240 |
75+
76+
*(基于可持续 QPS,按每台 4-CPU 实例 $40/月估算。)*
77+
78+
需要 4 台还是 31 台服务器的差距不仅是成本——而是运维复杂度。更少的服务器意味着更少的故障点、更简单的部署。
79+
80+
## 如何保证基准测试的可信度
81+
82+
- **CI 自动化** — 每个修改核心代码的 PR 自动触发
83+
- **系统调优** — 关闭 ASLR,CPU governor 设为 performance
84+
- **中位数聚合** — 消除异常值干扰,CV% 标记不稳定结果
85+
- **顺序隔离** — 一次只运行一个框架,运行间冷却
86+
- **相同硬件** — 同一个 GitHub Actions runner
87+
88+
完整测试套件开源:[github.com/childrentime/pareto/tree/main/benchmarks](https://github.com/childrentime/pareto/tree/main/benchmarks)
89+
90+
```bash
91+
npx create-pareto my-app
92+
cd my-app && npm install && npm run dev
93+
```
94+
95+
---
96+
97+
[Pareto](https://github.com/childrentime/pareto) — 轻量级流式 React SSR 框架 | [文档](https://paretojs.tech)

blog-external/benchmarks-medium.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# We Benchmarked Our SSR Framework Against Next.js — Here's What We Found
2+
3+
We built [Pareto](https://github.com/childrentime/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.
4+
5+
## What We Tested
6+
7+
Four scenarios covering the most common SSR workloads:
8+
9+
- **Static SSR** — Page with inline data, no async loader. Pure SSR throughput.
10+
- **Data Loading** — Loader with simulated 10ms DB query. SSR + data fetching overhead.
11+
- **Streaming SSR** — defer() + Suspense with 200ms delayed data. Streaming pipeline efficiency.
12+
- **API / JSON** — Pure JSON endpoint. Routing + serialization overhead.
13+
14+
All benchmarks on GitHub Actions (Ubuntu, Node 22, 4 CPUs), using autocannon with 100 connections for 30 seconds.
15+
16+
## Throughput: Requests Per Second
17+
18+
Static SSR: Pareto 2,224/s | **Next.js 3,328/s** | React Router 997/s | TanStack Start 2,009/s
19+
20+
Data Loading: **Pareto 2,733/s** | Next.js 293/s | React Router 955/s | TanStack Start 1,386/s
21+
22+
Streaming SSR: **Pareto 247/s** | Next.js 236/s | React Router 247/s | TanStack Start 247/s
23+
24+
API / JSON: **Pareto 3,675/s** | Next.js 2,212/s | React Router 1,950/s
25+
26+
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**.
27+
28+
## Load Capacity: Max Sustainable QPS
29+
30+
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.
31+
32+
- Data Loading: **Pareto 2,735/s** vs Next.js 331/s vs React Router 1,044/s
33+
- Streaming SSR: **Pareto 2,022/s** vs Next.js 310/s vs React Router 807/s
34+
- API / JSON: **Pareto 3,556/s** vs Next.js 1,419/s vs React Router 1,912/s
35+
36+
Under streaming SSR load, Pareto sustains **2,022 req/s** — that's **6.5x Next.js** and **2.5x React Router**.
37+
38+
**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**.
39+
40+
That's not just a benchmark number — it's a direct reduction in infrastructure cost, deployment complexity, and operational overhead.
41+
42+
## Latency
43+
44+
Under 100 concurrent connections, Pareto's data loading p99 is **702ms** while Next.js spikes to **7.82s**. In real terms: 99% of your users get their data-driven page in under 700ms with Pareto. With Next.js under the same load, 1 in 100 users waits nearly 8 seconds — long enough to close the tab.
45+
46+
## Bundle Size
47+
48+
Pareto ships **62 KB** of client JavaScript (gzipped) — roughly 1/4 of what Next.js sends (233 KB). On a typical 4G mobile connection (~5 Mbps), that's **100ms** to download vs **370ms**. On slower 3G (~1.5 Mbps), it's **330ms vs 1.2 seconds** just for the JavaScript.
49+
50+
## The Cost Difference
51+
52+
A SaaS dashboard serving 10,000 data-loading req/s at peak:
53+
54+
- **Pareto**: 4 servers (~$160/mo)
55+
- TanStack Start: 7 servers (~$280/mo)
56+
- React Router: 10 servers (~$400/mo)
57+
- Next.js: 31 servers (~$1,240/mo)
58+
59+
*(Based on sustainable QPS per framework, $40/mo per 4-CPU instance.)*
60+
61+
For a team growing from 1,000 to 10,000 DAUs, the difference between 4 servers and 31 servers isn't just cost — it's operational simplicity.
62+
63+
## How We Keep Benchmarks Honest
64+
65+
- **CI automated** — runs on every PR touching core code
66+
- **System tuning** — ASLR disabled, CPU governor performance mode
67+
- **Median aggregation** — eliminates outlier noise
68+
- **Sequential isolation** — one framework at a time
69+
- **Same hardware** — all frameworks on the same runner
70+
71+
The full suite is [open source](https://github.com/childrentime/pareto/tree/main/benchmarks). Run it yourself.
72+
73+
```
74+
npx create-pareto my-app
75+
cd my-app && npm install && npm run dev
76+
```
77+
78+
---
79+
80+
*[Pareto](https://github.com/childrentime/pareto) is a lightweight, streaming-first React SSR framework built on Vite. [Documentation](https://paretojs.tech)*

0 commit comments

Comments
 (0)