一名用户在 GitHub issue 中称,Codex 在本地持续写入 SQLite feedback 日志。路径包括 ~/.codex/logs_2.sqlite、logs_2.sqlite-wal 和 logs_2.sqlite-shm。
这台机器在约 21 天里,主 SSD 累计写入约 37TB。按这个速度折算,接近 640TB/年。对 1TB SSD 来说,大约相当于 640 次全盘写入。
这个数字不能直接套到所有 Codex 用户身上。它只是一个用户样本。但它问出了一个很硬的问题:Codex 是否把调试级日志默认持久化了,而且写得太多、太久、太底层?
问题不只是日志文件大,而是写入可能被放大
该用户给出的样本里,logs_2.sqlite 保留 681,774 行,估算 retained log bytes 约 1,035.6MiB。
单看 1GB 左右的保留数据,问题似乎不大。但 SSD 写入量不是这么算的。SQLite 的 WAL、索引、提交、检查点、剪枝,都会产生实际 I/O。
更关键的信号在 15 秒样本里:max row id 增加约 36,211 行,但 retained rows 没变。这指向一种更麻烦的模式:日志先被插入,再被剪掉。数据库大小受控,写入已经发生。
| 观察项 | 样本数据 | 更合理的读法 |
|---|---|---|
| 21 天 SSD 写入 | 约 37TB | 单机样本,不能外推到所有用户 |
| 年化写入 | 约 640TB/年 | 对 1TB SSD 约等于 640 次全盘写入 |
| retained rows | 681,774 行 | 只代表保留下来的行数 |
| retained log bytes | 约 1,035.6MiB | 不等于实际 SSD 写入量 |
| 15 秒插入 | 约 36,211 行 | retained rows 不变,疑似 insert-and-prune 写放大 |
我更在意的不是“Codex 生成了多少日志”,而是默认策略是否把排障工具变成了常驻写盘服务。
日志当然要有。AI 编程工具要排查 websocket、SSE、模型响应、工具调用、错误栈,没有日志很难定位问题。问题在于,默认长期落盘的级别和内容,应该比调试现场更克制。
真正的疑点是默认 TRACE 写进 SQLite
样本显示,TRACE 占 retained log bytes 约 70.7%。codex_otel.log_only 与 codex_otel.trace_safe 合计约 25.3%。
这说明保留内容的大头,来自低层级追踪日志、遥测镜像,以及 websocket/SSE 相关负载记录。
| 日志类别 | 占 retained log bytes | 暴露的问题 |
|---|---|---|
| TRACE | 约 70.7% | 默认持久化级别可能过宽 |
codex_otel.log_only + trace_safe | 约 25.3% | 遥测镜像增加本地保留负担 |
| websocket/SSE 相关负载 | 样本提到被写入 | 不应默认保存完整 payload |
这里要加一个限制:材料没有提供原始 websocket/SSE 内容,也不应该复原这些内容。讨论重点不是里面有什么隐私数据,而是这类原始负载是否应该默认写进本地 SQLite。
更稳妥的做法,是默认只保存事件类型、耗时、成功或错误、token 用量、payload 字节数。需要完整 payload 时,再让用户显式开启 debug 或导出诊断包。
这也是很多开发工具更常见的边界:普通日志用于定位大方向,TRACE 用于短期排障,不应默认长期开着。这里不能断言所有同类产品都这么做,但从工程常识看,长期全局 TRACE 落盘不是一个轻量选择。
对长时间开着 Codex CLI 或 Desktop 的开发者,这个差别很现实。工具窗口没报错,磁盘空间也未必暴涨,但 SSD 写入量可能一直在跑。
团队用户也要小心。把 Codex 放在远程开发机、工作站或 CI 辅助环境里,多进程叠加后,排查成本会更高。团队至少会先观望版本修复,或延后把它放进常驻环境,而不是直接大规模铺开。
用户现在能做什么,OpenAI 该改什么
目前不能确认 OpenAI 已经承认这是 bug,也不能确认修复已经发布。现阶段更合理的动作,是把它当成一个需要自查的日志写入风险。
Codex CLI/Desktop 用户可以先看三个文件是否异常增长:
- `~/.codex/logs_2.sqlite`
- `~/.codex/logs_2.sqlite-wal`
- `~/.codex/logs_2.sqlite-shm`
也可以用常规系统工具观察进程写入量和磁盘累计写入。重点不是只看数据库保留大小,而是看 WAL、系统写入计数和使用时长之间是否匹配。
如果你是个人开发者,最直接的动作是:暂时不要让 Codex 长时间无监督常驻;升级时留意 release notes 是否提到日志级别、SQLite sink、WAL 或 telemetry logging;发现写入异常就保留文件大小、时间窗口和系统写入数据,方便复现。
如果你负责团队环境,更实际的选择是:先限制常驻范围,避免在共享工作站或 CI 上默认长期开启;等日志上限、过滤规则或官方说明更清楚后,再决定是否扩展使用。
修复方向其实不复杂,难点在默认取舍:
| 修复点 | 该解决什么 |
|---|---|
| 取消 SQLite sink 默认全局 TRACE | 降低低价值日志持续写入 |
| 过滤依赖库 TRACE 日志 | 避免 inotify、tokio-tungstenite、OpenTelemetry SDK 等噪声落盘 |
| 避免默认保存完整 websocket/SSE payload | 降低隐私与写入风险 |
| 增加全局日志大小上限 | 防止保留数据失控 |
| 增加全局写入上限或速率限制 | 防止 insert-and-prune 写放大长期消耗 SSD |
这件事的主线并不复杂:一个本地 AI 编程代理,不能只按“能排障”来设计日志。它已经越来越像开发基础设施,就要按基础设施的标准控制默认成本。
回到开头那个 37TB。它未必代表每个人都会遇到同样问题,但足够提醒 Codex 用户检查一次本地写入。日志留在硬盘上,成本也留在硬盘上。
