编写于 2026-10-28
这是一次受控容量测量,答案是「1 GiB 宿主 RSS 能装多少空转 Agent」,不是「真实对话能跑多少」。空转 Agent 没有 prompt、工具调用和模型请求,真实负载的容量会更低;本文不给未经测量的折算倍数。
结论
- 1 GiB 宿主 RSS 下实测
N_max:219 / 220 / 222(三次独立 run,中位 220),N_stop:220 / 221 / 223。 - 每 Agent 边际内存 3.905–4.508 MiB(中位 4.380,
R²0.9907–0.9962),约 4.2 MiB。 - 首个 Agent 一次性增量 110.8–114.0 MiB;Manager 基线约 29–31 MiB。
- 优化前是
N_max = 20、39.6 MiB/agent、首个 +118.8 MiB、启动 p50 79.5 ms。容量提升约 11 倍,边际内存降到约九分之一。 - 提升来自共享
WebAssembly.Module:独立复核记录compileCalls = 1、instantiateCalls = 221,而优化前每个 Agent 都要重新编译约 10 MB 的 wasm。 - 从 200 个起步时 N=200 约 941–946 MiB,距 1024 MiB 约 80 MiB 余量。
口径
| 项 | 定义 |
|---|---|
| 测量对象 | 单宿主 Bun 进程构造一个 ChatManager,每个 Agent 是一个 chat 句柄 |
| 运行时 | chatConfig.runtime.kind = "wasm",每个 chat 建立独立 ACP session 后空转,不发送 prompt |
| 启动方式 | 串行启动,启动后不关闭、不销毁;默认每新增一个 Agent 采样一次 |
| 主指标 | 宿主进程 RSS:ps -o rss= -p <pid>,三次采样的中位数 |
| 停止条件 | 宿主 RSS ≥ 1024 MiB,或达到脚本上限,或启动失败 |
| 进程边界 | 本地 sqld 是独立进程,约 32 MiB,不计入宿主 RSS |
| 复测前提 | WASM 线性内存只增不减,同一进程跑过大 N 后 RSS 不会回落;每轮必须用全新进程 |
- 环境:Bun 1.4.3、macOS 26.6.2(arm64)、16 GiB RAM,运行期间主机负载约 1.7–2.3。
- 测量日期:2026-10-28。优化前后使用同一协议,优化后三次 run 中一次为独立复核。
N_max是initial仍低于 1024 MiB 的最大 N;N_stop是首个initial超过阈值的 N。启动失败单独记为 failure,不产生容量值。- 斜率为尾部最后 8 个已采样点的 OLS 拟合,单位 MiB/agent;
R² < 0.95视为未测稳。
结果
优化后三次 run:
| 指标 | run 1 | run 3(复核) | run 2 | 中位 | 极差 |
|---|---|---|---|---|---|
N_max |
219 | 220 | 222 | 220 | 219–222 |
N_stop |
220 | 221 | 223 | 221 | 220–223 |
| 每 Agent 边际(MiB) | 4.508 | 4.380 | 3.905 | 4.380 | 3.905–4.508 |
R² |
0.99207 | 0.99071 | 0.99617 | 0.99207 | 0.99071–0.99617 |
| 首个 Agent 增量(MiB) | 111.1 | 114.0 | 110.8 | 111.1 | 110.8–114.0 |
| 启动 p50(ms) | 45.92 | 45.457 | 46.235 | 45.92 | 45.457–46.235 |
| 启动 p95(ms) | 49.536 | 49.910 | 50.01 | 49.910 | 49.536–50.01 |
| 峰值 RSS(MiB) | 1025.922 | 1027.578 | 1025.734 | 1025.922 | 1025.734–1027.578 |
| N=200 RSS(MiB) | 945.719 | 944.109 | 941.406 | 944.109 | 941.406–945.719 |
| sqld 结束 RSS(MiB) | 32.531 | 31.984 | 32.563 | 32.531 | 31.984–32.563 |
优化前后对照:
| 指标 | 优化前 | 优化后 |
|---|---|---|
N_max |
20 | 219–222 |
| 每 Agent 边际 | 39.6 MiB | 约 4.2 MiB |
| 首个 Agent 增量 | +118.8 MiB | +110.8–114.0 MiB |
| 启动 p50 | 79.5 ms | 45.5–46.2 ms |
| N=20 总 RSS | 约 1015–1019 MiB | — |
三次 run 的 sessionId 全部唯一,失败数为 0,停止原因均为 rss。
提升来自哪里
- 优化前每个 Agent 都会重新编译约 10 MB 的 wasm。在该 Bun / JSC 版本上,即使连续编译同一份 buffer,也不复用编译产物,因此斜率约 39.6 MiB/agent。
- 共享
WebAssembly.Module后编译只发生在首次,后续 Agent 只承担实例、ACP session 与运行期数据,斜率降到约 4.2 MiB/agent。 - 首个 Agent 仍包含一次性编译、Emscripten 运行时与首个 session,所以首增量只从 118.8 MiB 降到 111–114 MiB,没有同比例下降。容量提升主要来自「不再每个 Agent 编译一次」。
N_max的 3 个 Agent 跨度来自尾部线性内存页增长和 GC 抖动,全宽约 1.4%,不是逻辑错误,也不应把 220 当作精确承诺。
边界与误判
- 空转不等于真实负载:没有 prompt、工具调用和模型请求,真实会话的常驻内存更高。本文只回答并发句柄的容量上限。
- 只覆盖 Bun + WASM 后端:native 后端、其他宿主运行时和托管部署不适用这份数字。
- 单机单版本:Bun 版本、宿主机或 wasm 产物变化后需要按同一协议复测。
- 不能用
process.memoryUsage().rss代替主指标:WASM 线性内存由实例持有,Bun 对该部分记账不完整。优化前 N=21 时ps为 1035.7 MiB,而process.memoryUsage().rss只有 676.2 MiB,差 359.5 MiB;优化后接近阈值时的最大差仍有 174.1–176.5 MiB。用后者会系统性高估容量。 - sqld 不在账内:部署时还要加约 32 MiB 的独立进程内存。
- 跨度不是分布:三次 run 只能说明这台机器上的重复性,不能当作跨环境的容量分布。
复现要点
- 先构建 SDK 产物,确认
dist/index.js、dist/wasm/peri-wasm.js、dist/wasm/peri_wasm.wasm存在;基准只消费构建产物,不从源码启动。 - 在第一个 WASM Agent 启动前拉起本地 sqld,每次 run 使用独立端口与独立
--db-path。 - 每轮使用全新进程采样,避免线性内存的历史峰值污染下一轮。
- 报告
N_max、N_stop、斜率与R²;R²低于 0.95 视为未测稳,不发布容量结论。
这项基准对应 4.4 的 WASM 模块共享变更,版本背景见 Peri 4.4 版本回顾。
