goals_1.sqlite write amplification: ~11 MB/s sustained writes (11 GB lifetime) on a 4 KB database

Open 💬 1 comment Opened Jun 12, 2026 by henrieri

What happened

The goals feature (features.goals, stable, default-on) produces pathological write amplification on $CODEX_HOME/goals_1.sqlite. The database file itself stays tiny (4–25 KB), but the process rewrites it continuously via WAL churn + fsyncs.

Measured on Linux (codex-cli 0.137.0, native codex-linux-x64 binary, headless agent sessions launched with --dangerously-bypass-approvals-and-sandbox):

  • One codex process: /proc/<pid>/io write_bytes = 8.7 GB after 771 s of uptime ≈ 11.3 MB/s sustained, with goals_1.sqlite, goals_1.sqlite-wal, and goals_1.sqlite-shm among its open fds. The sqlite file on disk is 25 KB.
  • A second longer-lived process showed 11.1 GB lifetime writes against a 4 KB goals_1.sqlite.
  • With 8 concurrent codex sessions on one host this adds up to 10–25 MB/s of pure overhead writes — measurable host IO pressure and real SSD wear (~1 TB/day per host).

Expected

Persisting goal state for a mostly-idle session should be a few KB per turn, not megabytes per second. Suggested fixes: debounce/coalesce goal persistence (write on state change, not per tick), batch into the existing state db transaction cadence, or relax durability (synchronous=NORMAL, fewer WAL checkpoints) for this low-value state.

Workaround

[features] goals = false in config.toml (or --disable goals) stops the churn entirely. We have rolled that out fleet-wide.

Environment

  • codex-cli 0.137.0 (npm @openai/codex, linux-x64 musl vendor binary)
  • Linux x86_64, ext4 on NVMe SSD
  • CODEX_HOME per-session directory; long-running interactive sessions

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗