codex - 💡(How to fix) Fix Excessive SQLite WAL writes during streaming due to TRACE logs ignoring RUST_LOG [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openai/codex#17320Fetched 2026-04-11 06:17:49
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
labeled ×3cross-referenced ×1unlabeled ×1

Error Message

The extension correctly sets RUST_LOG=warn when spawning the app-server process — confirmed via /proc/<pid>/environ: RUST_LOG=warn However, the SQLite logging sink appears to bypass or not respect the RUST_LOG filter, since TRACE-level entries are still persisted to logs_2.sqlite despite RUST_LOG=warn. The SQLite logging path appears to operate outside of the standard RUST_LOG filtering mechanism, or uses a separate filter configuration. WARN 44 These are low-level internal network events from tokio-tungstenite and hyper_util with no diagnostic value for end users. They should not be persisted to disk in a production binary — and critically, they are not suppressed by RUST_LOG=warn as one would expect. 2. Confirm RUST_LOG=warn is set: 5. Observe continuous pwrite64 calls to logs_2.sqlite-wal at ~5 MiB/s despite RUST_LOG=warn. RUST_LOG=warn should suppress TRACE and DEBUG output everywhere, including the SQLite logging sink. The current behavior — where RUST_LOG=warn suppresses stderr output but does not affect SQLite persistence — is inconsistent and undocumented. The SQLite logging sink in app-server should apply the same log-level filter as RUST_LOG (or the internal tracing subscriber filter), rather than maintaining a separate or hardcoded verbosity level. The fix should ensure that setting RUST_LOG=warn — as the extension already does — is sufficient to suppress TRACE/DEBUG writes to logs_2.sqlite.

Root Cause

The extension correctly sets RUST_LOG=warn when spawning the app-server process — confirmed via /proc/<pid>/environ:

RUST_LOG=warn

However, the SQLite logging sink appears to bypass or not respect the RUST_LOG filter, since TRACE-level entries are still persisted to logs_2.sqlite despite RUST_LOG=warn. The SQLite logging path appears to operate outside of the standard RUST_LOG filtering mechanism, or uses a separate filter configuration.

This was confirmed via strace during streaming:

pwrite64(20</home/k/.codex/logs_2.sqlite-wal>, ..., 4096, ...) = 4096
pwrite64(20</home/k/.codex/logs_2.sqlite-wal>, ..., 4096, ...) = 4096
...

And via SQLite query — MAX(id) jumped by ~5000 rows for a single short (~50 token) response, while total row count remained stable, indicating that rows are being rapidly inserted and pruned/rotated during streaming:

-- Before response:
SELECT MAX(id), COUNT(*) FROM logs;  -->  3088667 | 30141

-- After response:
SELECT MAX(id), COUNT(*) FROM logs;  -->  3093673 | 30141

Log level breakdown in logs_2.sqlite:

TRACE  20485  (68%)
INFO    8286
DEBUG   1326
WARN      44

Sample TRACE entries written during streaming:

target=hyper_util::client::legacy::pool   feedback_log_body="idle interval checking for expired"
target=log                                feedback_log_body="WouldBlock"
target=log                                feedback_log_body="/home/runner/work/codex/codex/.cargo-home/git/checkouts/tokio-tungstenite-..."

These are low-level internal network events from tokio-tungstenite and hyper_util with no diagnostic value for end users. They should not be persisted to disk in a production binary — and critically, they are not suppressed by RUST_LOG=warn as one would expect.

Fix Action

Workaround

Users can redirect logs_2.sqlite to tmpfs to protect their SSD while waiting for a fix:

# stop VSCodium first
mv ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite.bak
ln -s /tmp/logs_2.sqlite ~/.codex/logs_2.sqlite

Note: logs_2.sqlite contains only internal diagnostic logs — no conversation history — so data loss on reboot is acceptable.

After symlinking logs_2.sqlite to tmpfs, disk I/O from the Codex extension dropped to zero during streaming, confirming that the SQLite WAL is the sole source of the observed write load.

Code Example

RUST_LOG=warn

---

pwrite64(20</home/k/.codex/logs_2.sqlite-wal>, ..., 4096, ...) = 4096
pwrite64(20</home/k/.codex/logs_2.sqlite-wal>, ..., 4096, ...) = 4096
...

---

-- Before response:
SELECT MAX(id), COUNT(*) FROM logs;  -->  3088667 | 30141

-- After response:
SELECT MAX(id), COUNT(*) FROM logs;  -->  3093673 | 30141

---

TRACE  20485  (68%)
INFO    8286
DEBUG   1326
WARN      44

---

target=hyper_util::client::legacy::pool   feedback_log_body="idle interval checking for expired"
target=log                                feedback_log_body="WouldBlock"
target=log                                feedback_log_body="/home/runner/work/codex/codex/.cargo-home/git/checkouts/tokio-tungstenite-..."

---

cat /proc/$(pgrep -f 'codex.*app-server')/environ | tr '\0' '\n' | grep RUST_LOG

---

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

---

# stop VSCodium first
mv ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite.bak
ln -s /tmp/logs_2.sqlite ~/.codex/logs_2.sqlite
RAW_BUFFERClick to expand / collapse

What version of the IDE extension are you using?

openai.chatgpt-26.406.31014-linux-x64 (VSCodium on Linux Mint)

What subscription do you have?

ChatGPT Plus

Which IDE are you using?

VSCodium (Code - OSS fork)

What platform is your computer?

Linux x64 (Linux Mint)

What issue are you seeing?

During model streaming responses, the Codex app-server binary writes ~5 MiB/s (observed up to ~16 MiB/s in iotop) to ~/.codex/logs_2.sqlite-wal. This results in sustained disk write rates that can significantly impact SSD longevity and system performance.

This issue is independent of the thread-stream-state-changed warning spam and the open-in-targets retry loop, which were investigated separately.

Root cause

The extension correctly sets RUST_LOG=warn when spawning the app-server process — confirmed via /proc/<pid>/environ:

RUST_LOG=warn

However, the SQLite logging sink appears to bypass or not respect the RUST_LOG filter, since TRACE-level entries are still persisted to logs_2.sqlite despite RUST_LOG=warn. The SQLite logging path appears to operate outside of the standard RUST_LOG filtering mechanism, or uses a separate filter configuration.

This was confirmed via strace during streaming:

pwrite64(20</home/k/.codex/logs_2.sqlite-wal>, ..., 4096, ...) = 4096
pwrite64(20</home/k/.codex/logs_2.sqlite-wal>, ..., 4096, ...) = 4096
...

And via SQLite query — MAX(id) jumped by ~5000 rows for a single short (~50 token) response, while total row count remained stable, indicating that rows are being rapidly inserted and pruned/rotated during streaming:

-- Before response:
SELECT MAX(id), COUNT(*) FROM logs;  -->  3088667 | 30141

-- After response:
SELECT MAX(id), COUNT(*) FROM logs;  -->  3093673 | 30141

Log level breakdown in logs_2.sqlite:

TRACE  20485  (68%)
INFO    8286
DEBUG   1326
WARN      44

Sample TRACE entries written during streaming:

target=hyper_util::client::legacy::pool   feedback_log_body="idle interval checking for expired"
target=log                                feedback_log_body="WouldBlock"
target=log                                feedback_log_body="/home/runner/work/codex/codex/.cargo-home/git/checkouts/tokio-tungstenite-..."

These are low-level internal network events from tokio-tungstenite and hyper_util with no diagnostic value for end users. They should not be persisted to disk in a production binary — and critically, they are not suppressed by RUST_LOG=warn as one would expect.

What steps can reproduce the bug?

  1. Open a workspace in VSCodium/VS Code with the Codex extension.
  2. Confirm RUST_LOG=warn is set:
cat /proc/$(pgrep -f 'codex.*app-server')/environ | tr '\0' '\n' | grep RUST_LOG
  1. Run strace -f -e trace=pwrite64 -p $(pgrep -f 'codex.*app-server') in a separate terminal.
  2. Ask any question in the Codex chat panel and observe streaming.
  3. Observe continuous pwrite64 calls to logs_2.sqlite-wal at ~5 MiB/s despite RUST_LOG=warn.

Alternatively, check log level distribution after a session:

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

What is the expected behavior?

RUST_LOG=warn should suppress TRACE and DEBUG output everywhere, including the SQLite logging sink. The current behavior — where RUST_LOG=warn suppresses stderr output but does not affect SQLite persistence — is inconsistent and undocumented.

TRACE-level events from internal networking libraries (tokio-tungstenite, hyper_util) should never be written to the persistent SQLite log database during normal operation.

Additional information

Suggested fix

The SQLite logging sink in app-server should apply the same log-level filter as RUST_LOG (or the internal tracing subscriber filter), rather than maintaining a separate or hardcoded verbosity level. The fix should ensure that setting RUST_LOG=warn — as the extension already does — is sufficient to suppress TRACE/DEBUG writes to logs_2.sqlite.

Workaround

Users can redirect logs_2.sqlite to tmpfs to protect their SSD while waiting for a fix:

# stop VSCodium first
mv ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite.bak
ln -s /tmp/logs_2.sqlite ~/.codex/logs_2.sqlite

Note: logs_2.sqlite contains only internal diagnostic logs — no conversation history — so data loss on reboot is acceptable.

After symlinking logs_2.sqlite to tmpfs, disk I/O from the Codex extension dropped to zero during streaming, confirming that the SQLite WAL is the sole source of the observed write load.

extent analysis

TL;DR

The most likely fix is to modify the SQLite logging sink in the app-server to respect the RUST_LOG filter, preventing TRACE and DEBUG level logs from being written to logs_2.sqlite.

Guidance

  • Verify that the RUST_LOG=warn environment variable is correctly set for the app-server process using cat /proc/$(pgrep -f 'codex.*app-server')/environ | tr '\0' '\n' | grep RUST_LOG.
  • Check the log level distribution in logs_2.sqlite using sqlite3 ~/.codex/logs_2.sqlite "SELECT level, COUNT(*) FROM logs GROUP BY level ORDER BY COUNT(*) DESC" to confirm that TRACE and DEBUG level logs are being written.
  • To mitigate the issue, users can redirect logs_2.sqlite to a temporary file system (tmpfs) as a workaround, using mv ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite.bak and ln -s /tmp/logs_2.sqlite ~/.codex/logs_2.sqlite.
  • The app-server code should be modified to apply the same log-level filter as RUST_LOG to the SQLite logging sink, ensuring that setting RUST_LOG=warn suppresses TRACE and DEBUG writes to logs_2.sqlite.

Example

No code example is provided as the issue requires modification of the app-server code to respect the RUST_LOG filter.

Notes

The provided workaround redirects logs_2.sqlite to tmpfs, which may not be suitable for all users, especially those who require persistent logging. A permanent fix requires modifying the app-server code to respect the RUST_LOG filter.

Recommendation

Apply the workaround by redirecting logs_2.sqlite to tmpfs to protect the SSD from excessive write load, while waiting for a permanent fix to be implemented in the app-server code.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING