Skip to content

Instantly share code, notes, and snippets.

@jun76
Last active September 29, 2026 04:37
Show Gist options
  • Select an option

  • Save jun76/bf5f8fdde0e3866f537fc9422c65326d to your computer and use it in GitHub Desktop.

Select an option

Save jun76/bf5f8fdde0e3866f537fc9422c65326d to your computer and use it in GitHub Desktop.
Disable Codex SQLite diagnostic logging on Windows

Disabling Codex SQLite Diagnostic Logging on Windows

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.

Scope

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.

Overview of Issue #28224

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:

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.

What This Procedure Disables

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.

Prerequisites

Confirm that the Python Launcher is available:

py -3 --version

Quit 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.

Disable Diagnostic Logging

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.

Re-enable Diagnostic Logging

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)"

Data That Must Not Be Disabled

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.

Self-check

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.

Non-default SQLite Locations

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.

Related URLs

Status rechecked on September 29, 2026

Added on August 6

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.

Added on September 29

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.2 recorded 996 codex_app_server::outgoing_message rows 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 / bundled 0.155.0-alpha.9.2 measured 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.

Windows版CodexのSQLite診断ログを停止する手順

更新日:2026年9月29日

Warning

これはOpenAIが正式にサポートする設定ではなく、非公式の応急処置です。 フィードバックや障害調査に使われるローカル診断ログを停止します。 サポートへ提出するログを採取するときは、事前にログを再開してください。

対象

このメモは、Windows版Codex Desktopが%USERPROFILE%\.codex\logs_2.sqliteへ書き込む診断ログを停止する手順を扱う。

会話履歴やCodexの状態を保存する別のデータベースは対象にしない。

Issue #28224の概要

OpenAIの公式GitHubリポジトリには、CodexのSQLite診断ログがSSDへ大量に書き込まれる問題としてIssue #28224が報告された。

問題の中心は、次のSQLiteファイルだった。

  • %USERPROFILE%\.codex\logs_2.sqlite
  • %USERPROFILE%\.codex\logs_2.sqlite-wal
  • %USERPROFILE%\.codex\logs_2.sqlite-shm

報告環境では、TRACEレベルのイベントが高頻度で追加され、保持行数が一定でも挿入と削除が繰り返されていた。

この処理はSQLiteのWAL、インデックス、チェックポイントを更新するため、データベースの見かけ上のサイズより多くの書き込みをSSDへ発生させる。

Issueの報告者は、21日間でSSDの総書き込み量が約37TBに達したと報告した。

その後、主なログ発生源を削減する次の修正がマージされた。

報告者の環境ではログが約85%減少し、Issue #28224は2026年6月23日に閉じられた。

ただし、修正は診断ログを完全に無効化するものではない。

修正後のバージョンでもSQLite診断ログへの継続的な書き込みが報告されている(関連URL参照)ため、SSD書き込み量を重視する環境では実測と追加対策が必要になる。

停止するログの範囲

今回停止するのは、logs_2.sqlite内のlogsテーブルへ追加される診断レコードである。

通常の会話、ソースコード編集、コマンド実行には、この診断レコードを参照しない。

一方、ログを停止すると、次の用途で利用できる情報が減る。

  • /feedbackによる問題報告
  • クラッシュや通信障害の事後調査
  • OpenAIサポートへ提出する診断資料

この方法は公式の設定項目ではなく、SQLiteトリガーを使った応急処置である。

CodexのアップデートやログDBの再作成によって、設定が解除される可能性がある。

事前確認

Python Launcherが利用できることを確認する。

py -3 --version

続いて、Codex Desktop、Codex CLI、VS CodeのCodex拡張をすべて終了する。

タスクマネージャーを開き、Codexまたはcodex.exeが残っていないことも確認する。

実行中のプロセスがデータベースを保持したまま変更すると、ロック競合やWALの不整合を招く可能性がある。

診断ログの停止

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)"

このコマンドは、logsテーブルへのINSERTを無視するblock_log_insertsトリガーを作成する。

アプリケーションへエラーを返さずに挿入だけを破棄するため、ファイルを読み取り専用にする方法より再試行ループを起こしにくい。

実行後にCodexを起動し、通常どおり操作する。

診断ログの再開

障害調査やOpenAIサポートへの問い合わせ前には、診断ログを再開できる。

Codex関連プロセスをすべて終了してから、次のコマンドを実行する。

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)"

操作してはいけないデータ

次のファイルやディレクトリは、診断ログ停止の対象ではない。

  • %USERPROFILE%\.codex\state_5.sqlite
  • %USERPROFILE%\.codex\goals_1.sqlite
  • %USERPROFILE%\.codex\sessions
  • %USERPROFILE%\.codex\history.jsonl

.codexディレクトリ全体を読み取り専用にする操作も避ける。

これらにはスレッド、UI状態、Goals、セッション履歴などが保存される。

セルフチェック

最初に、停止用トリガーが存在することを確認する。

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())"

次のように表示されれば、トリガーは登録されている。

[('block_log_inserts',)]

続いて、Codexを起動した状態で次の60秒チェックを実行する。

チェック中にCodexで短い質問を送ると、ログ発生経路を動かした状態で確認できる。

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')"

trigger=TrueかつPASSと表示されれば、トリガーが存在し、観測中に新しいログIDが追加されていない。

既存ログの削除処理によって行数だけが減る可能性はあるため、判定には最大IDを使用している。

CHECK REQUIREDと表示された場合は、Codexを終了して停止コマンドを再実行する。

保存先を変更している場合

このメモのコマンドは、SQLite保存先が既定の%USERPROFILE%\.codexであることを前提にしている。

config.tomlのsqlite_homeまたはCODEX_SQLITE_HOME環境変数で保存先を変更している場合は、各コマンドのp=を実際のlogs_2.sqliteのパスへ置き換える。

関連URL

9/29 状態再確認

8/6追記

上記の後続Issueは、現在もすべてOpenのままである。マージ済みの修正によって当初のログ量は削減されたものの、SQLite永続ログのデフォルトがTRACEである挙動は変わっておらず、公式に無効化する設定も提供されていない。

最近の再現報告から、新しいバージョンでも問題が継続していることが確認できる。

  • 8/1、Issue #30236において、macOS版ChatGPT App 26.727.51351および同梱Codex CLI 0.145.0で、TRACE/DEBUGログの挿入とWALへの継続的な書き込みが再現された。
  • 8/4、Issue #35308において、Windows版Codex Desktop 26.727.6591.0およびApp Server 0.146.0-alpha.9.2でも、同様の挿入・削除処理の繰り返しが報告された。216秒間の計測で保持行数が変わらない一方、306件の新しいログIDが割り当てられ、そのうち71.6%がTRACEだった。

これらの報告は、以前の修正によって特に深刻だったログ発生源は大幅に削減されたものの、診断ログの継続的な書き込み自体は完全には解消されていないことを示している。

9/29追記

2026年9月29日(日本時間)に公開情報を再確認した。8月の追記後も対策は進んでいるが、SQLite診断ログを停止する公式の専用設定は確認できていない。

上記でOpenとしていた9件のIssueは引き続きOpenで、#28224はClosedのままである。SQLiteログのレベル設定を求める新しいIssue #43378もOpenになっている。

前回の追記以降の主な変更は次のとおり。

  • PR #39294:キュー上限を512件から2,048件、挿入バッチを128件から512件、定期フラッシュ間隔を2秒から10秒へ変更した。
  • PR #39592、PR #40658、PR #40726:DBやテレメトリーの診断出力が、さらにログ書き込みや送信を発生させる経路を抑制し、ログ永続化の計測も追加した。
  • PR #47886、PR #47887:SQLiteへの書き込み失敗時に診断情報をメモリーへ保持し、利用者へ警告する処理を追加した。診断情報を回収するための改善であり、ログ停止設定の追加ではない。
  • PR #49069:条件を満たすログDBの未使用ページをバックグラウンドで回収する処理を追加した。PR #49032、PR #49102では接続初期化時のロック待ちなども対策された。この3件は9/28 UTC(日本時間9/29)にマージされており、0.158.0の公開より後の変更である。配布済みDesktopのどのバージョンに反映されたかは、今回確認できていない。

0.158.0のソースでも、SQLiteログの既定値はターゲット別フィルター付きのTRACEで、codex_app_server::outgoing_messageは除外されていない。app-serverの実装では、RUST_LOGを使う標準エラー出力とSQLite側のフィルターが別々に設定される。現在の公式設定リファレンスにも、SQLite診断ログ専用の停止・レベル設定は記載されていない。

最近の実測報告は、バージョンと測定条件を合わせて読む必要がある。

  • 9/6のWindows報告では、0.150.0-alpha.12.2で21秒間に996件のcodex_app_server::outgoing_messageが記録された。TRACEの永続化が続くことは分かるが、件数だけでディスク書き込み量は判断できない。
  • より新しいmacOSの報告では、Desktop 26.915.31945/同梱0.155.0-alpha.9.2の60.91秒間の測定で、app-serverのプロセス書き込みは454,656バイト、ログ連番は220増加、WALの純増は519,120バイトだった。以前の「30秒で14~44MB」という規模はこの測定では再現していない。ただし負荷が異なるため、バージョン間の改善幅は断定できない。プロセスI/Oにはログ以外も含まれ、WALの純増も累積ディスク書き込み量とは異なる。

TRACEログの永続化は残っているが、現在のすべての環境で当初と同規模の大量書き込みが続くとまでは確認できない。本稿の非公式トリガーを使う必要性は、利用中のDesktop・同梱app-serverのバージョンと通常の負荷で再計測して判断する。今回の追記は公開報告とソースの確認であり、最新版Desktopで本手順を再検証した結果ではない。

@daaa1k

daaa1k commented Jul 28, 2026 •

Copy link
Copy Markdown

まとめていただいて、ありがとうございます。
セルフチェックの部分が PowerShell だとエラーになったので、こっちの方が良いかもしれません。

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())"
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')"

@jun76

jun76 commented Jul 28, 2026 •

Copy link
Copy Markdown
Author

コメントありがとうございます。

ご指摘頂きました通り、元のコマンドでは私の手元でも cmd: 成功、pwsh: 失敗 になりました。失礼いたしました。
ご提案頂きました修正で cmd/pwsh ともに成功することを確認いたしましたので、記事本文に反映いたしました。
ありがとうございました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment