单进程 4096 个会话:pi-durable 把数据库提交合批后,CPU 也顺带快了
Mario Zechner 给 pi-durable 做了一轮性能优化。每个 agent 步骤都要落库,旧实现让 commit 排队,128 个会话时单次运行等约 25 秒。合批后降到 0.28 秒,本地 SQLite 快 18% 到 58%。注意测试用假模型和空工具,测的是基线。
durable 的账单总是后付。每一步都落库,崩溃恢复干净,平时就得等 IO。pi-durable 这次做的是把账单合起来付。
Mario Zechner 在推文里给了一个数字:单个 Node 进程跑到 4096 个会话时,系统明显饱和,但还能用。
先把背景补齐。pi-durable 的 durable 来自落库:agent 每走一步,先把状态写进数据库,然后才继续。1 次保存等于 1 次 commit。一次 agent run 大约 12 次 commit。崩溃发生在中途,就从最后一次 commit 恢复。代价是每一步都要等数据库。
旧实现慢在串行等待。session 把每个 commit 单独发给数据库,然后等返回。一次 DB 往返 4ms,每个会话的 commit 排在其他会话后面。128 个会话时,一次 run 要等约 25 秒才轮到自己。Mario 的改法是:一个 commit 在途中时,后面堆积的 commit 合到下一次 DB 调用一起发。128 个会话时,一次 DB 调用大约带走 33 个 commit。等待从约 25 秒降到 0.28 秒。
合批听起来简单,麻烦在依赖。不能把所有 commit 无脑打包,单个 commit 之间可能有读写依赖。Mario 说这块相当棘手。有网友追问崩溃场景:数据库提交完一批,但调用方还没收到 ack 时杀掉 coordinator,再恢复,依赖读取和工具调用能不能干净重放。Mario 回复 yes。
效果不只在网络数据库。本地 SQLite 快了 18% 到 58%。Cloudflare Durable Objects 读取少 40% 行,写入少 13% 行,静态内存不变。
主图标题把提升写成 46 次/秒到 772 次/秒。底部小字更具体:本地 SQLite 在 2048 个对话时从 88 次/秒到 459 次/秒;三个并行工具在 2048 个对话时从 58 次/秒到 617 次/秒;单个对话性能保持不变。
限定条件容易被忽略。Mario 在回复里注明:测试用的是进程内假模型 provider 和无操作工具。这组数据测的是 harness 能跑出的基线计算量。换成真实、吃 CPU 或 I/O 的工具,runs/s 会下降。
对跑多 agent 的开发者,结论比较直接。如果 coordinator 通过 Postgres 之类扇出到几十个子 agent,不用再为了吞吐把 session 分片。瓶颈先落在单个 CPU 上,Node 进程会先饱和。真到 CPU 打满,再考虑分片。
有网友 Mykyta Pavlenko 总结得挺准:修完存储后 CPU 白赚,说明进程之前只是在等 commit。4096 个会话,一次 run 约 12 次保存,放在一个 Node 盒子里,已经算能干活的范围。Mario 感谢 @she_llac 催他动手。
发布时间: 2026-10-31 13:33