Last updated: September 29, 2026
Warning
This is an unofficial workaround, not an OpenAI-supported configuration. It disables local diagnostic records used for feedback and troubleshooting. Re-enable logging before collecting data for a support request.
This note explains how to stop the Windows Codex Desktop app from writing diagnostic records to %USERPROFILE%\.codex\logs_2.sqlite.
It does not disable the separate databases that store conversation and application state.
Issue #28224 in OpenAI's official GitHub repository reported that Codex SQLite diagnostic logging was generating excessive SSD writes.
The affected files were:
%USERPROFILE%\.codex\logs_2.sqlite%USERPROFILE%\.codex\logs_2.sqlite-wal%USERPROFILE%\.codex\logs_2.sqlite-shm
In the reported environment, high-frequency TRACE events were continuously inserted and deleted even when the retained row count remained stable.
These operations update the SQLite WAL, indexes, and checkpoints, so the amount written to the SSD can be much larger than the visible database size.
The reporter observed approximately 37 TB of total SSD writes over 21 days.
The following changes were subsequently merged to reduce the main sources of diagnostic-log traffic:
- Stop logging every Responses WebSocket event, PR #29432
- Filter noisy targets from persistent logs, PR #29457
- Stop persisting bridged log events, PR #29599
The reporter observed an approximately 85% reduction in log traffic and closed Issue #28224 on June 23, 2026.
These changes did not disable diagnostic logging completely.
Continuing SQLite diagnostic writes have been reported in later versions (refer to the related URLs), so environments where SSD write volume matters should measure the current behavior and apply an additional mitigation if necessary.
This procedure prevents new diagnostic records from being inserted into the logs table in logs_2.sqlite.
Normal conversations, source-code editing, and command execution do not depend on these diagnostic records.
Disabling them does reduce the information available for:
- Submitting a report through
/feedback - Investigating crashes or connection failures
- Providing diagnostic evidence to OpenAI Support
This is a workaround based on a SQLite trigger, not an official Codex configuration option.
A Codex update or recreation of the log database may remove the trigger.
Confirm that the Python Launcher is available:
py -3 --versionQuit Codex Desktop, all Codex CLI sessions, and any VS Code instance running the Codex extension.
Open Task Manager and verify that no Codex or codex.exe processes remain.
Changing the database while another process holds it open may cause lock contention or WAL inconsistency.
Run the following command in PowerShell:
py -3 -c "import sqlite3,os; p=os.path.expanduser(r'~\.codex\logs_2.sqlite'); c=sqlite3.connect(p); c.execute('CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;'); c.commit(); print('Diagnostic logging disabled:',p)"This creates a trigger named block_log_inserts that silently ignores every INSERT into the logs table.
Because the trigger discards inserts without returning an application error, it is less likely to cause a retry loop than making the database read-only.
Start Codex again and use it normally.
Diagnostic logging can be restored before troubleshooting a problem or contacting OpenAI Support.
Quit all Codex-related processes, then run:
py -3 -c "import sqlite3,os; p=os.path.expanduser(r'~\.codex\logs_2.sqlite'); c=sqlite3.connect(p); c.execute('DROP TRIGGER IF EXISTS block_log_inserts'); c.commit(); print('Diagnostic logging enabled:',p)"Do not apply this workaround to the following files or directories:
%USERPROFILE%\.codex\state_5.sqlite%USERPROFILE%\.codex\goals_1.sqlite%USERPROFILE%\.codex\sessions%USERPROFILE%\.codex\history.jsonl
Do not make the entire .codex directory read-only.
These locations contain thread metadata, UI state, goals, session history, and other runtime state.
First, verify that the blocking trigger exists:
py -3 -c "import sqlite3,os; p=os.path.expanduser(r'~\.codex\logs_2.sqlite'); c=sqlite3.connect(p); print(c.execute('SELECT name FROM sqlite_master WHERE type=\'trigger\' AND name=\'block_log_inserts\'').fetchall())"The following output confirms that the trigger is registered:
[('block_log_inserts',)]
Next, start Codex and run this 60-second check:
py -3 -c "import sqlite3,os,time; p=os.path.expanduser(r'~\.codex\logs_2.sqlite'); q=lambda: sqlite3.connect(p).execute('SELECT COUNT(*), COALESCE(MAX(id),0) FROM logs').fetchone(); t=sqlite3.connect(p).execute('SELECT 1 FROM sqlite_master WHERE type=\'trigger\' AND name=\'block_log_inserts\'').fetchone(); a=q(); print('trigger=',bool(t),'before=',a); time.sleep(60); b=q(); print('after=',b); print('PASS' if t and b[1]==a[1] else 'CHECK REQUIRED')"Send a short prompt to Codex during the 60-second interval to exercise the normal logging path.
If the command reports both trigger=True and PASS, the trigger exists and no new log IDs were inserted during the observation period.
The existing row count may decrease because of cleanup, so the check uses the maximum row ID for its pass or fail decision.
If it reports CHECK REQUIRED, quit Codex and run the disable command again.
The commands in this note assume that SQLite state is stored in the default %USERPROFILE%\.codex directory.
If the location has been changed through sqlite_home in config.toml or the CODEX_SQLITE_HOME environment variable, replace the value assigned to p in each command with the actual path to logs_2.sqlite.
Status rechecked on September 29, 2026
- [Open] 2026-04-10 — Issue #17320: Excessive SQLite WAL writes during streaming due to TRACE logs ignoring RUST_LOG
- [Closed] 2026-06-14 — Issue #28224: Codex SQLite feedback logs can write ~640 TB/year and rapidly consume SSD endurance
- [Open] 2026-06-26 — Issue #30236: Codex App writes high-volume TRACE logs to logs_2.sqlite despite RUST_LOG=warn
- [Open] 2026-06-28 — Issue #30405: Windows Codex still persists high-frequency TRACE logs to logs_2.sqlite WAL
- [Open] 2026-07-04 — Issue #31132: Log level not configurable — logs_2.sqlite grows to 1.4GB with hardcoded TRACE
- [Open] 2026-07-07 — Issue #31478: High-frequency TRACE writes to logs_2.sqlite after restart
- [Open] 2026-07-08 — Issue #31542: logs_2.sqlite TRACE churn — root cause and minimal fix
- [Merged] 2026-07-09 — PR #31789: Stop persisting RMCP service traces
- [Merged] 2026-07-09 — PR #31790: Reduce MCP tool-list trace volume
- [Merged] 2026-07-09 — PR #31791: Filter routine Hyper logs from SQLite
- [Merged] 2026-07-09 — PR #31792: Summarize streamed response item logs
- [Open] 2026-07-20 — Issue #34291: Large rmcp::service TRACE rows bypass the noisy-target filter
- [Open] 2026-07-24 — Issue #35092: Codex CLI 0.145.0 still persists per-SSE TRACE events to SQLite
- [Open] 2026-07-25 — Issue #35308: Persistent SQLite TRACE churn remains in bundled 0.146.0-alpha.3.1
All follow-up issues listed above remain open. The merged mitigations reduced the original log volume but did not change the persistent SQLite sink's TRACE-default behavior or provide a supported setting to disable it.
Recent reproductions show that the issue remains present in newer builds:
- On August 1, Issue #30236 reproduced continuing TRACE/DEBUG inserts and WAL activity with ChatGPT App 26.727.51351 and bundled Codex CLI 0.145.0 on macOS.
- On August 4, Issue #35308 reported the same insert-and-prune churn on Windows with Codex Desktop 26.727.6591.0 and App Server 0.146.0-alpha.9.2. During a 216-second sample, 306 new log IDs were allocated while the retained row count remained unchanged; 71.6% of the new rows were TRACE.
These reports indicate that the earlier fixes substantially reduced the most severe traffic sources but did not fully resolve persistent diagnostic-log writes.
Checked on September 29, 2026 (JST). Further mitigations have been merged since the August update, but a supported control to disable the SQLite diagnostic-log sink has not been confirmed.
The nine previously listed open issues remain Open; #28224 remains Closed. The newer Issue #43378, requesting a configurable SQLite log level, is also Open.
Changes since the previous update:
- PR #39294 increased the queue capacity from 512 to 2,048 entries, the insert batch size from 128 to 512, and the periodic flush interval from 2 to 10 seconds.
- PR #39592, PR #40658, and PR #40726 filtered database/telemetry diagnostics that could generate further logs or exports, and added measurements of log persistence.
- PR #47886 and PR #47887 retain failure diagnostics in memory and warn users when SQLite log writes fail. These changes improve diagnostic recovery; they do not provide a logging-off setting.
- PR #49069 added background reclamation of unused pages in eligible log databases. PR #49032 and PR #49102 address connection-initialization locks and related stalls. These three PRs were merged on September 28 UTC (September 29 JST), after the 0.158.0 release; their availability in distributed Desktop builds has not been confirmed here.
The 0.158.0 source still defaults to TRACE with target-specific filters, and does not filter codex_app_server::outgoing_message. App-server wiring applies RUST_LOG to stderr separately from the SQLite filter. The current configuration reference does not document a dedicated SQLite diagnostic-log disable/level setting.
Recent measurements need to be read with their build and workload:
- A September 6 Windows report on
0.150.0-alpha.12.2recorded 996codex_app_server::outgoing_messagerows in 21 seconds. This confirms continued TRACE persistence; the row count alone does not measure disk-write volume. - A newer macOS report on Desktop
26.915.31945/ bundled0.155.0-alpha.9.2measured 454,656 bytes of app-server process writes over 60.91 seconds, a log-sequence increase of 220, and 519,120 bytes of net WAL growth. The earlier 14–44 MB per 30-second magnitude did not recur in that sample. Different workloads prevent a direct cross-version comparison; process I/O includes non-log writes, and net WAL growth is not cumulative disk I/O.
Persistent TRACE logging remains, while the available evidence does not establish that every current build has the original excessive write rate. Reassess the need for this unofficial trigger using the actual Desktop/app-server version and a representative workload. This update reviews public reports and source code; it does not revalidate the workaround on the latest Desktop build.
まとめていただいて、ありがとうございます。
セルフチェックの部分が PowerShell だとエラーになったので、こっちの方が良いかもしれません。