Yesterday, a developer named Uzi posted a screenshot on X showing something alarming: OpenAI Codex had apparently written 37 TB of data to somebody’s SSD in just 21 days.
That works out to roughly 640 TB per year if uncorrected. On a typical 1 TB NVMe drive rated for 600 TBW (terabytes written), that’s the entire warranted lifespan in under 12 months.
The thread blew up.
A GitHub issue was filed.
OpenAI merged fixes within a day.
But here’s the thing: those fixes are landing in waves, and early reports suggest the first wave didn’t fully solve it.
Here’s what actually happened, what’s been fixed, what hasn’t, and what you should do right now if you’re a heavy Codex user.
The Bug: SQLite Feedback Logging at TRACE Level
Codex keeps a local diagnostic database at ~/.codex/logs_2.sqlite (and its WAL and SHM companion files). This is where it stores feedback logs — structured records about what the tool did, what errors occurred, and what telemetry it collected.
The intention is reasonable: if something breaks, OpenAI can ask you to send those logs.
The problem is that Codex attached that SQLite sink with a global default of TRACE — the most verbose logging level available. Every WebSocket payload, every OpenTelemetry mirror event, every dependency’s inotify event got written to disk.
Why “Visible File Size” Is Deceptive
Here’s the part that confused a lot of people. The logs_2.sqlite file on your drive might only be 1-2 GB. How does that square with 37 TB of writes?
The answer is SQLite’s insert-and-prune cycle.
Codex keeps about 1,000 rows per thread partition in that database. When new rows come in, old rows get deleted in the same transaction. The pruning keeps the retained row count stable, so the file on disk doesn’t grow forever.
But every insert writes to the SQLite WAL (Write-Ahead Log). Every delete writes to the WAL. When the WAL checkpoints, that data gets synced back to the main database file. And because Codex never runs incremental_vacuum, freed pages accumulate as freelist bloat — the file stays large even when “empty.”
One user captured the gap perfectly: their logs_2.sqlite had 506,149 retained rows, but the SQLite autoincrement counter had already advanced past 5.5 billion IDs. That’s a 10,000x gap between what’s stored and what’s been written and thrown away.
What Was Actually Being Logged
Community analysis of the retained rows showed a clear picture. About 70% of the data by volume was TRACE level logs. The biggest sources:
- WebSocket response payloads — every successful message from the AI response stream, dumped in full
- OpenTelemetry mirrors — telemetry events duplicated into local storage
- Bridged dependency logs — low-level Rust library events (tokio-tungstenite WebSocket internals, inotify file-watching events, hyper HTTP client pool activity)
- SSE event streams — server-sent event payloads
A single row of codex_api::endpoint::responses_websocket TRACE could be 40+ KB. Multiply that by thousands of inserts per minute and you get the picture.
The Fix (and Why It’s Not Quite Done Yet)
OpenAI engineer jif-oai merged two PRs for the 0.142.0 release on June 22, 2026:
- PR #29432 stops logging every websocket response payload at TRACE level
- PR #29457 filters out OpenTelemetry mirror targets (
codex_otel.log_only,codex_otel.trace_safe) and bridgedtarget=logevents from the SQLite sink
The 0.142.0 release notes mention it under Chores: “Reduced persistent-log churn by removing per-event WebSocket payload logging and filtering duplicated telemetry records.”
A third fix, PR #29599, targets bridged target=log events that bypassed the first two filters. It’s in the 0.143.0 alpha builds.
But here’s where it gets complicated. Multiple users tested 0.142.0 and reported the problem persists:
- One user measured 10 MB/s of writes (~315 TB/year) on Linux after updating
- A macOS user logged 463,000 inserts in 21 minutes on 0.142.0
- Another user’s idle Desktop app was still inserting ~10 rows per second
The issue has been reopened on GitHub. The hyper_util TRACE logs, in particular, appear to still be flowing through.
The SSD Endurance Problem
This isn’t just an annoyance. SSDs have a finite number of write cycles before the NAND flash cells wear out. Consumer drives are rated in TBW:
- Samsung 990 Pro 1TB — 600 TBW
- WD Black SN850X 1TB — 600 TBW
- SK Hynix Platinum P41 1TB — 750 TBW
- MacBook Air/Pro soldered SSDs — ratings vary, but the drive CANNOT be replaced
At 640 TB per year, even a high-endurance drive hits its rated limit in under 12 months. And on modern MacBooks where the SSD is soldered to the motherboard, that’s not a drive replacement — it’s a whole-laptop problem.
One user reported that Codex itself estimated “low-single-digit millions of dollars of SSD endurance burned across users,” with a higher estimate reaching “low tens of millions.”
What Codex Users Should Do Right Now
1. Update to the latest version
If you’re on Codex CLI: codex update (or re-download from openai.com/codex).
For the Desktop app, check for updates in the app menu. The 0.142.0 release (Desktop build 26.616.71553) contains the first round of fixes. 0.143.0 alpha builds are rolling out rapidly.
The fix IS real — it just may not be complete for all usage patterns yet.
2. Check your log file size
Look in ~/.codex/ (Linux/macOS) or %USERPROFILE%\.codex\ (Windows).
If logs_2.sqlite is over 500 MB, you’re affected. If it’s over 1 GB, you’re heavily affected.
To check SQLite internals:
sqlite3 ~/.codex/logs_2.sqlite "SELECT MAX(id) as max_id, COUNT(*) as retained;"If max_id is thousands of times larger than retained, your system has been churning through writes even if the file looks stable.
3. Apply the SQLite trigger workaround (recommended for heavy users)
Until 0.143.0 ships stable, the safest community workaround is a SQLite trigger that blocks new inserts to the log table. It’s reversible and does not delete any existing data.
Stop Codex first, then run this:
sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"Windows (PowerShell): “powershell sqlite3 "$env:USERPROFILE\.codex\logs_2.sqlite" "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;" “
To undo later (e.g., after the final fix ships): “bash sqlite3 ~/.codex/logs_2.sqlite "DROP TRIGGER IF EXISTS block_log_inserts;" “
Important caveat: This is a community workaround, not an official fix. Future Codex updates might drop or recreate the table. If you need to submit a diagnostic report to OpenAI, undo the trigger first so the logs can be captured.
4. Do NOT delete the WAL files while Codex is running
SQLite’s WAL and SHM files are live state files. Deleting them while Codex has the database open can corrupt the database and crash the application.
If you want to reclaim disk space from an already-bloated log database, here’s the safe procedure:
- Quit Codex completely
- Add the trigger (see above)
- Run
DELETE FROM logs;andVACUUM;on the database - Restart Codex
5. Monitor your SSD health
You can check your drive’s total bytes written to see if you’ve been affected:
Windows: Open CrystalDiskInfo or run this PowerShell command: “powershell Get-PhysicalDisk | Get-StorageReliabilityCounter | Select-Object DeviceId, Wear, TotalBytesWritten “
macOS: Use smartctl (from brew install smartmontools): “bash smartctl -a disk0 | grep "Data Units Written" “
Linux: “bash smartctl -a /dev/nvme0n1 | grep "Data Units Written" “
6. Optional: Redirect logs to RAM
If you’re technical and want zero SSD impact while waiting for the final fix, you can symlink the codex log files to a RAM disk (/dev/shm on Linux, a ramdisk volume on macOS, ImDisk on Windows). This eliminates all write wear from the logging — at the cost of losing logs on reboot.
What Comes Next
OpenAI is clearly working on this. The speed of the fix (first report June 14, PRs merged by June 22) shows they took it seriously. But the fix rollout is happening in stages, and 0.142.0 wasn’t the final word.
The 0.143.0 builds are in alpha right now. Once stable ships, the remaining churn from bridged dependency logs should be resolved. In the meantime, the SQLite trigger workaround is safe, reversible, and proven to drop write rates from thousands of rows per minute to single digits.
I’ll update this post when 0.143.0 stable drops with confirmation of whether it finally closes the gap. In related Codex news, I also covered how Codex rate limit resets are now bankable — another quality-of-life change worth knowing about.
Got a different experience with the Codex logging bug? Hit me up on X or drop a comment below.



