`~/.codex` 悄悄吃掉几个 GB:rollout 会话与 SQLite 日志的磁盘占用排查

2026-08-09

如果你的系统盘剩余空间一路吃紧,清完 npm 缓存、清完 Docker 镜像仍不见回血,那值得顺手翻一眼用户目录下那个平时根本不会打开的 ~/.codex

它确实能长到很大。在 codex-cli 0.147.0(Windows 11)上执行 codex doctor --summary,Notes 分组里就明明白白挂着一条 rollouts 提示:405 active files · 3.07 GB on disk。同一台机器上 ~/.codex 里还有一个 SQLite 日志库文件 logs_2.sqlite,单个文件 763 MB。加起来接近 4 GB,而这台机器从没有人主动”存”过什么东西——都是日常用 Codex(OpenAI Codex)攒下来的。

这篇按排查顺序走一遍:怎么确认是它、能动的处置有哪些、改完怎么验、以及什么迹象说明你找错方向了。

一、先把 ~/.codex 里的占用分成四类

盲目 du 一把然后开始删文件,是这类问题最容易翻车的地方。先建立一张地图。在 codex-cli 0.147.0(Windows 11)上,~/.codex(也就是 CODEX_HOME)里实际观测到的条目,按”会不会长大、能不能动”可以分成四类:

类别目录/文件特点
会话 rolloutsessions/(按年份分子目录)、archived_sessions/history.jsonl用一次涨一点,doctor 会单独统计
SQLite 库logs_2.sqlite 及其 -shm-walmemories_1.sqlitegoals_1.sqlite单文件可以很大,目录里看不出来
其它产物与配置log/(内含 codex-tui.log)、cache/.tmp/browser/computer-use/generated_images/memories/automations/ambient-suggestions/.sandbox/大小差异大,需要单独看
不该动的config.tomlauth.jsonAGENTS.mdinstallation_idauth.json 官方明确要求当密码看待

需要点名的是第二类。logs_2.sqlite 这种单文件库,在资源管理器里按目录排序、或者只看目录数量,很容易被漏掉——你会以为”文件才十几个能有多大”,结果一个文件就七百多兆。所以排查一定要按体积排,不是按数量排。

二、怎么确认占用大头到底在哪

第一条命令:codex doctor --summary

codex doctor --summary

在 codex-cli 0.147.0(Windows 11)上,它的抬头是 Codex Doctor v0.147.0 · windows-x86_64,输出按 Notes / Environment / Configuration / Updates / Connectivity / Background Server 分组。跟磁盘直接相关的有三行:

  • Notes 分组的 rollouts:本机提示 405 active files · 3.07 GB on disk。这就是会话 rollout 的官方口径统计,不用自己数。
  • Environment 分组的 state:本机显示 databases healthy。它管的是那几个 SQLite 库健康与否。
  • Environment 分组的 threads:本机显示 rollout files and state DB thread inventory agree——rollout 文件和 state 库里的 thread 清单对得上

第三行很关键,后面讲处置时还要回头用它。

状态符号一共观测到四种:(ok)、(idle)、(notes/warn)、(fail)。结尾会打一行统计,格式像 17 ok · 1 idle · 1 notes · 0 warn · 0 fail ok。磁盘这个问题在本机是以 notes 出现的,不是 warn 也不是 fail——它不会红着脸拦你,只是安静地记一笔,所以很多人用了很久也没注意到。

如果列表被截断了,加 --all 展开:

codex doctor --all

第二条:看具体是哪个文件大

doctor 只报 rollouts 的合计,SQLite 库有多大它不直接给数字。这一步得用系统自带命令(这不是 Codex 提供的功能,只是普通的目录统计,本文也没有把它列进实测范围):

Windows PowerShell:

Get-ChildItem "$env:USERPROFILE\.codex" -Recurse -File |
  Sort-Object Length -Descending |
  Select-Object -First 20 FullName, @{n='MB';e={[math]::Round($_.Length/1MB,1)}}

Git Bash / macOS / Linux:

du -sh ~/.codex/* | sort -h | tail -20

拿到列表后对照第一节那张表,你就能一眼判断大头落在哪一类。

第三条:确认配置本身是好的

排查之前先确认你读到的配置是生效的配置。在 codex-cli 0.147.0(Windows 11)上做过一次刻意的破坏性验证:执行 codex -c 'features=[unclosed' doctor --summary(传了一段语法不合法的 TOML),命令没有崩溃退出doctor 照常跑完,但 Notes 区多了一行:

✗ config       config could not be loaded - Fix the reported config error, then rerun codex doctor.

这个行为对排查很有用:配置写坏了不会拦住你,只会让配置默默不生效。所以凡是”我明明改了配置为什么没效果”,第一步都该是跑 doctor 看这一行是不是

要贴给别人看的时候

codex doctor --json

官方对这个选项的说明是 “Emit a redacted machine-readable report”——是脱敏的。要开 issue 或者发给同事看,用它比截图整个终端稳妥。顺带一提,codex mcp listEnv 列在 codex-cli 0.147.0(Windows 11)上也会把环境变量值打成 *****,只留键名,同样是可以贴出去的输出。

三、能动的处置,按依据强弱分三层

第一层:有明确子命令的

在 codex-cli 0.147.0(Windows 11)上,codex --help 里列着这几个跟会话生命周期直接相关的子命令:

  • resume:Resume a previous interactive session。不带参数会弹选择器,--last 直接续最近一次。
  • archive / unarchive:按 id 或会话名归档 / 取消归档已保存会话。
  • delete:按 id 或会话名永久删除已保存会话。
  • fork:Fork a previous interactive session。

要腾空间,delete 是这一层唯一名正言顺的手段;archive 的语义是归档,本机 ~/.codex 下确实有一个独立的 archived_sessions/ 目录,所以别指望归档能省磁盘——它更像换个抽屉放。想先看看都有哪些会话可选,直接跑 codex resume 让它弹选择器就行。

第二层:有配置键可以止血或者搬家

这一层是”以后别再涨这么快”和”涨也别涨在系统盘”。相关键都出自官方《Configuration Reference》页:

官方给的取值/默认对磁盘的意义
history.persistencesave-allnone控制历史是否持久化
history.max_bytes历史的字节上限
log_dir默认 $CODEX_HOME/log日志目录可以挪走
sqlite_homeSQLite 库的落点可以挪走
tool_output_token_limit工具输出的 token 上限
features.rollout_budget.enabledfalseunder developmentrollout 预算跟踪

几个要说清的点:

history.persistence 大概率管的是 history,不是 rollout。 在本机观测里,history.jsonlsessions/~/.codex 下两个各自独立的条目,据此判断这个键管的是前者。但它对 doctor 报的那个 rollouts 数字有没有影响,我们没有实测过,别把它当清理 rollout 的手段来用。这是最容易踩空的一脚。

log_dirsqlite_home 是”搬家”不是”减肥”。 把它们指到数据盘,系统盘立刻回血,但总占用没变。好处是从此不再报警,坏处是你更不会去看它了——建议搬完在日历上给自己留个复查提醒。

features.rollout_budget.enabled 目前标注的是 under development,默认 false 名字看着正是为这个问题准备的,但官方把它标为 under development,这类开关不适合当稳定功能来依赖,生产机器上尤其别指望它的行为稳定。

还有一组键容易被误当成清理策略,这里专门澄清:Memories 相关的 memories.max_rollout_age_days(默认 30,范围 0–90)、memories.max_rollouts_per_startup(默认 16,上限 128)、memories.min_rollout_idle_hours(默认 6,范围 1–48)看起来都带 rollout 字样,很容易让人以为是”多少天以上的 rollout 自动清掉”。但官方在《Configuration Reference》的 Memories 一节里只给了这三个键的默认值和取值范围,并没有把它们描述成清理策略;它们究竟对应什么行为,我们没有核实到,所以别指望改它们能让 rollouts 的占用变小。顺便说一句,features.memories 官方默认 false,本机 codex features list 实测生效值也是 false

一段可以直接拿去改的示例(改前先备份 ~/.codex/config.toml):

# ~/.codex/config.toml
log_dir = "D:/codex-data/log"
sqlite_home = "D:/codex-data/sqlite"

[history]
persistence = "save-all"
max_bytes = 52428800

以上为按官方文档键位组合的示例,未逐项实测,以官方文档为准。

不想改配置文件、只想临时试一下,可以用顶层的 -c

codex -c log_dir="D:/codex-data/log" doctor --summary

在 codex-cli 0.147.0(Windows 11)上,-c 的官方说明是覆盖 ~/.codex/config.toml 里的值,点号路径表示嵌套,value 按 TOML 解析、解析失败则按字面字符串处理——这条对路径特别要注意,Windows 路径里的反斜杠在 TOML 里是转义字符,写正斜杠更省心。

第三层:单次任务不落盘

如果你有一类高频的自动化调用(比如 CI 里、脚本里反复跑),它们贡献的会话文件往往占了大头。codex exec 有一个专有选项:

codex exec --ephemeral "你的指令"

--ephemeral 的官方说明只有一句:不把会话文件落盘。至于不落盘之后 resumefork 这些依赖已保存会话的子命令还能不能用,官方说明没提,我们也没有实测——按”不落盘”字面理解就够了,凡是事后可能要回看的调用,别用它。

明确不写的一层

网上一定能搜到”直接把 ~/.codex/sessions/ 整个删掉”这种建议。本文不给这条路径——不是矫情,是有具体理由:doctor 的 Environment 分组里有一项 threads,本机显示 rollout files and state DB thread inventory agree,它校验的正是rollout 文件与 state 库里的 thread 清单是否一致。手工删文件之后这一项会不会转成不一致、会不会影响 resume,我们没有实测过,官方文档在我们核对的范围内也没有说明 rollout 文件可否安全手工删除。既然 codex delete 这个正规入口存在,就用它。

四、处置完怎么验证

按顺序过三关,缺一关都可能是”看着好了其实没好”:

  1. 重跑 codex doctor --summary,对比 Notes 里 rollouts 那行的文件数和 GB 数是不是降了。这是唯一直接的证据。
  2. 看 Environment 的 statethreads 两行state 应该还是 databases healthythreads 应该还是 rollout 文件与 state DB 清单一致。改了 sqlite_home 之后这两行尤其要看——库搬了位置,健康状况得重新确认。
  3. 在 doctor 输出里找 config 这一项。正常态它在 Configuration 分组里显示为 config(loaded);本机实测把配置写坏时,✗ config config could not be loaded ... 这行出现在 Notes 区。所以别只盯着 Configuration 分组找——两个地方都扫一眼。只要看到 ✗ config,就说明你的改动根本没加载,前面看到的任何”变化”都跟你的配置无关。

再补一个陷阱。--strict-config 这个选项的作用是”config.toml 里出现本版本不认识的字段时直接报错退出”,听上去正好可以用来验证键名有没有拼错。但在 codex-cli 0.147.0(Windows 11)上实测过:执行 codex -c model_reasoning_effortt=high --strict-config exec --help(注意 effortt 是故意拼错的),命令正常打印了 help,没有报未知字段错误。也就是说校验发生在真正加载配置去跑会话的时候,--help 这类不进入会话的路径不触发校验。别拿 --help 跑通当作”配置写对了”的证明。

五、什么迹象说明不是这个原因

排查最怕一条道走到黑。下面几种情况,说明你该换个方向:

doctor 报的 rollouts 只有几百 MB,磁盘照样满。 那大头在别处。回到第二节的文件体积排序,重点看 logs_2.sqlite(本机单文件 763 MB)以及 -shm-wal 这两个伴生文件,还有 cache/.tmp/。这几个 doctor 的 Notes 不会替你统计。

~/.codex 整体才几百 MB。 那磁盘问题跟 Codex 无关,别在这儿耗着,回去查真正的大户。

你统计的目录是空的或者小得离谱。 检查 CODEX_HOME 是不是被改到了别处。有一条实测线索可以交叉验证:codex exec--ignore-user-config 官方说明是”不加载 $CODEX_HOME/config.toml但 auth 仍然使用 CODEX_HOME”——说明这个环境变量是全局生效的落点,改了它,你在默认位置当然什么都看不到。

同事的机器上目录长得跟你不一样。 不同机器上的目录清单本来就可能有出入,第一节那张表是本机 codex-cli 0.147.0(Windows 11)上观测到的结果,不是标准答案,别拿别人的清单当基准去找”我这儿怎么少了一个”。还有一点要提醒:目录在不在,跟功能开没开不是一回事——本机 codex features listmemories 的生效值是 false,但 memories/ 目录和 memories_1.sqlite 都实实在在躺在那儿。

你记得的版本号和现在的对不上。 在同一台机器上,本次采集开头执行 codex --version 得到 codex-cli 0.131.0,十几分钟后再执行同一命令得到 codex-cli 0.147.0which -a codex 全程只有一个可执行文件。Codex 具备自更新能力(config.toml 里的 check_for_update_on_startup 官方默认就是 true),所以”昨天看到的版本号和今天不一样”是正常现象。排查任何跟版本有关的问题,都以当次 codex --version 的实时输出为准,不要用记忆里的版本号。

最后一句实在话:这个问题不是 bug,是长期使用的必然结果。与其等磁盘报警再来救火,不如现在就跑一次 codex doctor --summary,把 Notes 里那行数字记下来,过一个月再跑一次——你会对自己的增长速度有个数,也就知道该不该现在就把 log_dirsqlite_home 挪到数据盘去。

相关阅读


本文依据 Codex 官方文档(learn.chatgpt.com/docs/ 的《Configuration Reference》页面)整理,核对日 2026-08-09;文中标注「本机实测」的部分基于 codex-cli 0.147.0 / Windows 11 环境下的只读命令输出,我们未发起过任何模型对话请求。目录统计用的系统命令不在实测范围内。产品功能、模型与价格以官方最新说明为准。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。