Skip to content
郭立 (leeguoo)

Is Codex Really Secretly Burning Through Your SSD? I Dug Through My Own Machine

People are sharing claims that Codex secretly writes logs like crazy and burns through SSDs. Local test: the file stays stable at 126 MB thanks to rolling cleanup, but over 10 days it inserted 8.45 million rows, and the writes came from the background desktop app-server. The original post is basically directionally correct; only the “everyone will definitely burn through an SSD in a year” part is exaggerated. Includes root cause (source code + GitHub issue) and cleanup options.

Will Codex Write Your SSD to Death?
I Checked My Local Logs

People are sharing a warning: Codex writes to logs_2.sqlite at high frequency in the background. The file does not look large, but actual writes may be high. I first thought it was an exaggerated headline, but after checking my local logs, I changed my mind.

Rumor vs truth: a crowd treats a small log file as a fire-breathing hard-drive monster, while a detective measures it with a ruler and finds the file really is not large
The file is only 126 MB. The problem is not its size, but the inserts and deletes behind it.

Update 2026-06-24: OpenAI has acknowledged this bug and merged a fix, and #28224 was briefly closed—but was soon reopened, because the latest stable version 0.142.0 still has not fully fixed it. The complete fix is only in 0.143-alpha, released that day. After upgrading this machine to 0.142.0, three tests still showed writes, users on multiple platforms reproduced it, and even OpenAI’s own fix commit identifies the cause—see the section “Just update and it’s fixed?” below.

①What People Are Saying Online

I saw two types of claims: one is reposted screenshots that simply say Codex is burning through disks; the other is lencx’s source-code and issue review.

The reposted version says: after installing Codex CLI, it writes data to ~/.codex/logs_2.sqlite at high frequency; the file does not appear to grow, but SSD writes keep increasing.

The evidence-based version comes from lencx(浮之静)’s “Codex Logs Are Burning Your SSD”. He went through the Codex source code and a series of GitHub issues, pointing the problem at the default configuration of the SQLite logging layer: TRACE-level network events, telemetry mirroring, and dependency-library noise are written into a persistent database, so file size does not represent actual write volume.

I checked my own machine in that direction. Below, I only include local commands and verifiable issues, rather than drawing conclusions from secondhand retellings.

②What I Found on My Own Machine

A detective uses a magnifying glass to inspect log lines in a terminal, with three sticky notes beside it: 18/sec, 10 days, automatic rotation
I checked just three things: how large the file is, what it writes, how fast it writes, and whether it grows indefinitely.

First, the files:

$ ls -lh ~/.codex/logs_2.sqlite*

logs_2.sqlite      126M
logs_2.sqlite-wal  4.9M
logs_2.sqlite-shm   32K

In the database, 66% is TRACE. The content is not business logs, but low-level instrumentation for websocket polling reads and writes:

$ sqlite3 ~/.codex/logs_2.sqlite "SELECT level,count(*) FROM logs GROUP BY level ORDER BY 2 DESC"

TRACE  65744      -- 66%
INFO   17968
DEBUG  13459
WARN    1974
ERROR      8      -- about 99,000 rows total at the time

The latest few entries looked like this:
TRACE  log  WouldBlock
TRACE  log  tokio-tungstenite/compat.rs:157 Read read -> poll_read
TRACE  codex_api::endpoint::responses_websocket  ...

Looking only at the current row count is not enough. This database writes and deletes at the same time, so its size can mislead you.

The Writer Is the Desktop App, Not the CLI You Type Into

The original post described the problem as “the CLI is writing.” I checked the process_uuid in the logs, and the latest 500 rows all came from the same process:

$ ps -p 2950 -o command

/Applications/Codex.app/Contents/Resources/codex app-server

The writes came from the app-server of Codex desktop(Codex.app). At the time, I did not have an interactive codex terminal open. A more accurate statement is not “the CLI is burning through the disk,” but “a running Codex process writes to this shared SQLite logging layer”; the desktop app, TUI, and editor extensions may all participate.

The File Is Only 126 MB, but It Wrote 8.45 Million Rows in 10 Days

The primary key is an auto-incrementing id. I checked the current id range and actual row count:

$ sqlite3 ~/.codex/logs_2.sqlite "SELECT min(id), max(id), count(*) FROM logs"

min(id)   206,551,383
max(id)   215,003,791     -- auto-increment has reached 215 million
count(*)      101,406     -- but only 100,000 rows remain

Range span: 8.45 million; actual remaining rows: 100,000  =>  8.35 million rows have already been deleted

This is an “insert-prune” loop: the table only keeps roughly the most recent 10 days of rows(the oldest row on my side was exactly 10 days old), and old rows are deleted. Seeing a stable 126 MB file with ls does not mean nothing is being written. The auto-incrementing id shows that 8.45 million rows were actually inserted over 10 days, and 8.35 million of them were deleted.

This overturned my first assessment. I had originally estimated based on the “remaining 100,000 rows” and concluded it was “about 7 MB/day,” even calling it clickbait. Calculated from the actual 8.45 million inserted rows, it is about 600 MB/day of log body text, meaning I undercounted by nearly 90x. And this is only logical writes; WAL, four indexes, checkpointing, and deletion itself all write to disk again.

The upstream issues show even larger magnitudes: #17320 measured WAL writes of about 5–16 MiB/s during streaming output, and a single 50-token response made MAX(id) jump by about 5,000 rows; the reporter of #28224 said it wrote about 37 TB over 21 days, extrapolating to about 640 TB/year. My earlier sample where “it only grew by 109 rows in 6 seconds” only captured an idle period; the high-write window is during model output.

"Just update to a newer version"? Not that simple (verified on 2026-06-24)

This needs to be unpacked. OpenAI did merge two noise-reduction PRs in 0.142.0 (released on 2026-06-22), including #29457, and #28224 was closed for a while. But it was soon reopened (the issue's state_reason is now reopened)—because the fix was incomplete: people on macOS, Windows, and Linux all reported that writes continued after upgrading to 0.142.0, and someone measured ~10 MB/s, about 315 TB/year with iotop.

I reproduced it on my own machine too. After upgrading both the CLI and the desktop core to 0.142.0, it was still writing at ~18 lines/second while idle and spiking into the thousands during streaming output, still writing things like TRACE/log and TRACE/hyper_util. Why didn't the partial patch work? OpenAI explained it themselves in the real fix commit, #29599:

"The disk filter in 0.142.0 disables target=log, but dependency library logs are filtered by their original dependency target before tracing-log relabels them as target=log, so they slipped through—and high-frequency dependency TRACE kept going into SQLite."

This complete fix is not in any stable release; it only landed in 0.143.0-alpha, released on 2026-06-24. As of this verification, both #28224 and #17320 are still Open. So the accurate version is: upstream has reduced the noise, and the full fix is on the way, but upgrading to the current latest stable version does not count as fixed yet.

③Is it true or false?

A balance scale: the TRUE side is very heavy, the FALSE side is raised, and a FUD stamp is being stamped on the FALSE side
The mechanism is real; claims like "everyone will burn through their SSD in a year" go too far.

Point by point:

ClaimMeasurementVerdict
Secretly writes to logs_2.sqlite Really exists, 126 MB True ✓
Writes "tens of thousands" of junk entries An underestimate. 8.45 million rows inserted in 10 days, 66% of them websocket TRACE True (and more than that) ✓
It writes even if you do nothing Basically true. I did not open the CLI, but the background desktop app-server was still writing; as long as a Codex process is running, websocket polling may keep emitting TRACE True ✓
The file does not look larger, but underneath it is writing like crazy That is exactly the pathology. Rolling deletion keeps the size stable, but physical writes do not stop True ✓
It will burn through your SSD in a year Depends on usage. Heavy users should care; light users do not need to panic Exaggerated ≈

Where the root cause is (source code dug up by lencx)

When app-server and the TUI start, both attach a SQLite logging layer, whose default filter is:

.with_filter(Targets::new().with_default(Level::TRACE))

In other words, this disk sink accepts TRACE by default and has its own filter chain, so it is not constrained by RUST_LOG=warn. The reporter of #17320 had already set RUST_LOG=warn, but TRACE entries still kept appearing in logs_2.sqlite. That issue was opened on 2026-04-10 and was still Open when checked.

SSD risk depends on write volume

An SSD's TBW is the warrantied write amount, not a death line where the drive fails as soon as you cross it. Risk depends on usage intensity, drive capacity, and free space:

  • Heavy users: If you are at 640 TB/year like #28224, and that lands on a soldered 256 GB Mac SSD (rated around 150 TBW), you can exceed the warrantied write amount in a few months. That is worth addressing.
  • Light users: If write volume is one or two orders of magnitude lower, the drive can still last many years, so there is no need to panic.

There is another misconception: it will not "burn through the same tiny spot." SSDs have FTL and wear leveling; writing to the same filename does not mean repeatedly erasing the same flash cells. What you should really look at is total host writes, plus write amplification when the disk is too full.

There is another easily overlooked privacy risk: lencx points out that several issues mention this library may write raw websocket/SSE payloads to disk, which means conversation fragments may be mixed in. So do not treat logs_2.sqlite as a "harmless cache" and casually upload, back up, or publish it.

My conclusion: the mechanism is real, upstream evidence exists, and I can still reproduce it locally; but it is not "everyone burns through their SSD in a year." It depends on which Codex processes you keep running, how long you use it each day, and your machine's SSD capacity and free space. My first version only looked at residual row counts and judged it as FUD; that was wrong.

④What to do

A broom sweeps a large 126MB box into a small 5MB box, while an SSD beside it smiles and gives a thumbs-up
Cleanup can reclaim space, but it cannot stop continued writes. These are two separate things.

Most of the following comes from lencx's postmortem, and I verified it on my machine. Fully quit Codex before taking action, otherwise you may hit the file-handle problem from #22444: the process is still holding the deleted WAL, so du looks lower, but df does not release the space.

First confirm no process is holding it

pgrep -fl 'Codex|codex|app-server'
lsof -nP | grep -E '\.codex/.+logs_2\.sqlite'

Clean up and reclaim space (symptom treatment)

# After confirming Codex has exited
sqlite3 ~/.codex/logs_2.sqlite 'DELETE FROM logs; VACUUM;'

This can shrink the file from 126 MB back to a few MB, but it cannot stop it from starting to write again. Cleanup ≠ rate limiting.

Temporary stopgap: block new writes (symptom treatment, but effective)

sqlite3 ~/.codex/logs_2.sqlite \
  "CREATE TRIGGER IF NOT EXISTS block_log_inserts
   BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"

# Roll back
sqlite3 ~/.codex/logs_2.sqlite "DROP TRIGGER IF EXISTS block_log_inserts;"

The trigger ignores all inserts, and the effect is immediate. The tradeoff is that feedback_log_body becomes empty, so bug reports will lack diagnostic attachments; if an upgrade recreates the table, the trigger may be deleted, so recheck after upgrading.

Move the database to another disk (workaround)

# ~/.codex/config.toml
sqlite_home = "/Volumes/ExternalDisk/codex-sqlite"
# Or temporarily: CODEX_SQLITE_HOME=/Volumes/ExternalDisk/codex-sqlite codex

This is cleaner than symlinking a single file, but it only moves the writes elsewhere; it does not reduce them. If the external disk is disconnected or sleeps, Codex will be affected. Note that it migrates the entire SQLite home, so state, logs, goals, and memories will all move with it.

Three traps to avoid

  • /tmp symlinks are useless on macOS: macOS points /tmp to /private/tmp, which is on the APFS system disk, not a RAM disk. Symlinking there merely moves it from one SSD directory to another, doing nothing to reduce writes. Verify it yourself with readlink /tmp; mount | grep -i tmpfs.
  • RUST_LOG=warn cannot control this sink: it can quiet stderr, but this SQLite persistence layer has its own filtering chain (see #17320).
  • [feedback] enabled = false is not a switch: it only disables the feedback submission flow; the logging layer is still attached at startup.

While you're at it: exclude WAL/SHM from backups

--exclude='*.sqlite-wal'
--exclude='*.sqlite-shm'

WAL and SHM are runtime files; syncing tens of GB to another machine is usually just copying the problem.

Upstream still needs to tighten this further

All of these are only stopgaps. Codex still needs to narrow the default level of the disk sink further, avoid writing raw websocket payloads by default, cap WAL and total size, and provide an explicit switch (such as sqlite_log_level). #28224 has been closed due to a noise-reduction PR, but #17320, #22444, #24275, and #28997 were still Open when checked.


Take one minute to decide whether you need to care: first run ls -lh ~/.codex/logs_2.sqlite* to check the size, then run SELECT max(id),count(*) FROM logs once. If max(id) is in the tens or hundreds of millions while the row count is only a few hundred thousand, your machine is also "writing, deleting, then writing again." If you use it heavily, especially on a Mac with a soldered SSD, it is worth addressing; if you only use it occasionally, just knowing about it is enough.

All data in this article was measured on the author’s own machine under ~/.codex/ (codex-cli 0.134.0), with terminal output left unmodified. Source-code location, workaround review, and upstream scale data come from lencx (Fu Zhijing) “Codex Logs Are Burning Your SSD”; this article independently reproduced and verified the issue on the author’s own machine. Illustrations were generated by ChatGPT.

Reference issues (checked on 2026-06-23):

  • #17320 — TRACE logs ignore RUST_LOG and write heavily to WAL during streaming output
  • #28224 — about 37 TB in 21 days, extrapolated to about 640 TB/year; closed on 2026-06-22 after a noise-reduction PR was merged
  • #22444 — space is not released after deleting the WAL (the process still holds the handle)
  • #24275 · #28997 — WAL grows to tens of GB under normal use

More in this category · AI & Agent

← previous
chrome-use: Let Any AI Agent Directly Drive Your Logged-In Real Chrome, with CreepJS Rating It 0% Bot
next →
You Can’t Import a GSI by Itself

Comments

Replies are public immediately and may be moderated for policy violations.

Max 1000 characters.