Why Codex Can Exhaust Your SSD: A Full Technical Investigation
The article analyzes how intensive use of OpenAI Codex, especially long‑running agents, continuously writes to its local SQLite logs, causing massive SSD write amplification despite modest file size growth, and details community reports, OpenAI’s fixes, and practical mitigation steps.
When Codex runs intensive or long‑running agents it writes diagnostic data to a local SQLite database in WAL mode located at ~/.codex/logs_2.sqlite (and its -wal and -shm companion files). The file size may stay around a few hundred MiB, but the SSD write volume can increase dramatically because new rows are constantly inserted while old rows are deleted, causing repeated rewrites of the same pages.
Initial observation
On the author’s machine the files measured: logs_2.sqlite ≈ 823 MiB logs_2.sqlite‑wal ≈ 38 MiB
A quick TRACE estimate gave ~70.6 MiB of logged content. In a 15‑second window MAX(id) grew by 10 364 while the total row count remained unchanged, indicating a constant insert‑delete cycle.
Community reports
Issue #17320 (10 Apr 2026) reported that streaming output writes to logs_2.sqlite‑wal at MB/s rates.
Subsequent reports (May–June 2026) described WAL files that kept growing because an old Codex process held an open handle on a deleted file, and UI slowdown after a few minutes of normal Desktop use.
One user measured ~37 TB SSD writes over 21 days (≈ 640 TB per year) on a machine with continuous log growth.
Root‑cause analysis
Codex stores diagnostic logs in a SQLite database using WAL mode. The problem is excessive logging:
Every successful streaming response, tool‑state refresh, and parsed response is recorded as a log entry.
TRACE‑level debugging events, intended for temporary debugging, are persisted to disk.
The logs table retains a constant number of rows, but MAX(id) keeps increasing because old rows are deleted while new ones are added. This creates high‑frequency page rewrites without increasing the visible file size.
OpenAI’s fix
On 22 June 2026 two pull requests authored by collaborator jif‑oai were merged:
#29432 – stops recording every WebSocket response event.
#29457 – filters out high‑frequency, low‑value TRACE logs from being written.
The changes are included in the pre‑release tags rust‑v0.142.0‑alpha.11 and rust‑v0.142.0‑alpha.12. Open issues #17320 , #22444 and #24275 (WAL lifecycle, deleted‑file handling, desktop log inflation) remain open.
Diagnostic workflow
Users can verify whether their installation still exhibits rapid log growth with the following read‑only steps:
# Show file sizes (ignore missing files)
du -h ~/.codex/logs_2.sqlite* 2>/dev/null
ls -lh ~/.codex/logs_2.sqlite* 2>/dev/null
# Inspect schema and log distribution
DB="file:$HOME/.codex/logs_2.sqlite?mode=ro"
sqlite3 "$DB" "PRAGMA table_info(logs);"
sqlite3 "$DB" "PRAGMA journal_mode; PRAGMA wal_autocheckpoint; SELECT COUNT(*) AS rows, MIN(id), MAX(id) FROM logs; SELECT level, COUNT(*) AS rows, ROUND(SUM(estimated_bytes)/1024.0/1024.0,1) AS mib FROM logs GROUP BY level ORDER BY SUM(estimated_bytes) DESC;"
# Short‑window sampling (15 s)
before_id=$(sqlite3 "$DB" "SELECT COALESCE(MAX(id),0) FROM logs;")
before_cnt=$(sqlite3 "$DB" "SELECT COUNT(*) FROM logs;")
sleep 15
after_id=$(sqlite3 "$DB" "SELECT COALESCE(MAX(id),0) FROM logs;")
after_cnt=$(sqlite3 "$DB" "SELECT COUNT(*) FROM logs;")
echo "id_delta=$((after_id-before_id))"
echo "count_delta=$((after_cnt-before_cnt))"
# Detect lingering Codex processes holding the files
lsof -nP ~/.codex/logs_2.sqlite* 2>/dev/nullIf id_delta is large while count_delta is near zero, the database is likely still undergoing the insert‑delete cycle.
Temporary mitigation (read‑only environment)
When an immediate stop‑gap is needed, a SQLite trigger can block further inserts and truncate the WAL. This suppresses future diagnostic logs but preserves existing data.
sqlite3 ~/.codex/logs_2.sqlite "
CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;
PRAGMA wal_checkpoint(TRUNCATE);
"To remove the trigger later:
sqlite3 ~/.codex/logs_2.sqlite "DROP TRIGGER IF EXISTS block_log_inserts;"Before applying any destructive action, back up the log files:
backup_dir="$HOME/.codex/logs_backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"
find "$HOME/.codex" -maxdepth 1 -name 'logs_2.sqlite*' -exec cp -p {} "$backup_dir"/ \;Takeaway
The core issue was that high‑frequency TRACE logging caused massive SSD write amplification even though the on‑disk file size grew only modestly. The two merged PRs ( #29432 and #29457 ) eliminate the primary write‑amplification bug. Users of Codex—especially those who keep agents running for hours or days, run multiple Codex processes, or use low‑durability storage—should upgrade to a version containing the fixes (≥ 0.142.0‑alpha.11) and monitor the log files to ensure id_delta no longer spikes.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
