Codex app logs_2.sqlite high-frequency WAL writes from TRACE/streaming events

Open 💬 4 comments Opened Jul 5, 2026 by chengyanqi
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex app on Windows appears to continuously write high-volume local runtime logs into ~/.codex/logs_2.sqlite / WAL, suspected TRACE or streaming event logging. This caused visible local disk churn and WAL growth during normal Codex desktop usage.

Environment

  • OS: Windows, native Codex desktop app
  • Codex app package observed locally: OpenAI.Codex_26.623.13972.0_x64__2p2nqsd0c76g0
  • Codex executable path observed: C:\Program Files\WindowsApps\OpenAI.Codex_26.623.13972.0_x64__2p2nqsd0c76g0\app\resources\codex.exe
  • Runtime database: C:\Users\A\.codex\logs_2.sqlite
  • Date observed: 2026-07-05 Asia/Shanghai

Evidence collected

Initial readonly file-size check:

  • logs_2.sqlite: 61,251,584 bytes, 58.41 MiB
  • logs_2.sqlite-wal: 3,221,872 bytes, 3.07 MiB
  • logs_2.sqlite-shm: 32,768 bytes, 0.03 MiB

15 second file-level sampling before mitigation:

  • logs_2.sqlite: 61,251,584 bytes -> 61,251,584 bytes
  • logs_2.sqlite-wal: 4,132,392 bytes -> 4,132,392 bytes
  • WAL LastWriteTime advanced during the sample window

After temporary mitigation, file-size check:

  • logs_2.sqlite: 61,251,584 bytes, 58.41 MiB, LastWrite 2026/7/5 12:11:36
  • logs_2.sqlite-wal: 4,239,512 bytes, 4.04 MiB, LastWrite 2026/7/5 12:12:29
  • logs_2.sqlite-shm: 32,768 bytes, 0.03 MiB, LastWrite 2026/7/5 12:04:27

sqlite3 and lsof were not available in PATH, so detailed level distribution and open-handle inspection were not completed.

Temporary local mitigation applied

A user-confirmed SQLite trigger was added to stop further inserts into logs:

CREATE TRIGGER IF NOT EXISTS block_log_inserts
BEFORE INSERT ON logs
BEGIN
  SELECT RAISE(IGNORE);
END;

Readback confirmed:

trigger=('block_log_inserts', 'logs')

This is only a local emergency workaround. It silently drops future local log rows and should not be considered a proper fix.

Expected behavior

Codex should not continuously write high-volume TRACE/streaming-event logs to local SQLite during normal desktop use, or it should expose a documented way to bound, rotate, sample, disable, or lower the verbosity of this runtime log stream.

Actual behavior

The local SQLite runtime log database and WAL showed ongoing write activity and WAL growth. User perceived it as high-frequency disk writes.

Request

Please investigate whether Codex desktop is over-logging TRACE/streaming events into logs_2.sqlite, especially on Windows, and provide an official fix or mitigation that does not require modifying the SQLite schema manually.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #31034
  • #30405
  • #30162
  • #29799
  • #31111

Powered by Codex Action

lixuru217 · 1 month ago

Additional macOS reproduction evidence for logs_2.sqlite high-frequency writes.

Environment:

  • OS: macOS
  • Codex CLI visible in PATH: codex-cli 0.133.0
  • Codex Desktop app config environment: BROWSER_USE_CODEX_APP_VERSION = "26.623.141536"
  • Runtime DB: /Users/lixuru/.codex/logs_2.sqlite
  • Observation date: 2026-07-07, America/Phoenix

Local read-only checks used:

  • SQLite URI: file:$HOME/.codex/logs_2.sqlite?mode=ro
  • lsof only for open-handle inspection
  • No VACUUM, no checkpoint/truncate, no schema changes, no process kill

Evidence before config experiment:

  • The Codex process held logs_2.sqlite, logs_2.sqlite-wal, and logs_2.sqlite-shm.
  • Database size: 462139392 bytes.
  • WAL size at one baseline check: 4420792 bytes.
  • Current logs table state:
  • COUNT(*) = 57198
  • MIN(id) = 208527087
  • MAX(id) = 253595912
  • latest log time: 2026-07-07 02:57:22
  • Recent 60 second distribution:
  • TRACE log: 981 rows, 125277 estimated bytes
  • TRACE codex_app_server::outgoing_message: 19 rows, 3220 estimated bytes
  • TRACE codex_api::sse::responses: 16 rows, 16404 estimated bytes
  • DEBUG codex_core::stream_events_utils: 12 rows, 23348 estimated bytes
  • TRACE codex_mcp::connection_manager: 12 rows, 9032 estimated bytes

Earlier same-machine 60 second quiet sampling after update:

  • Start: MAX(id) = 253494040 at 2026-07-07 01:05:40
  • End: MAX(id) = 253497196 at 2026-07-07 01:06:40
  • MAX(id) advanced by 3156 while COUNT(*) stayed constant at 57198.
  • This suggests a rolling retention/prune behavior can hide ongoing writes if observers only watch row count.
  • WAL mtime advanced during the quiet sample.

Config workaround experiments:

  • Tried adding:

``toml
[feedback]
enabled = false
`
After a normal Codex restart, a 60 second quiet sample still advanced
MAX(id) from 253632139 to 253634131` and WAL mtime continued advancing.

  • Tried adding:

``toml
[feedback]
enabled = false
max_bytes = 67108864
`
After a normal Codex restart, a 60 second quiet sample still advanced
MAX(id) from 253698415 to 253700711` and WAL mtime continued advancing.

  • The post-restart sample after max_bytes still showed the same dominant sources:
  • TRACE log: 946 rows
  • TRACE codex_api::sse::responses: 37 rows
  • TRACE codex_app_server::outgoing_message: 36 rows
  • DEBUG codex_core::stream_events_utils: 7 rows
  • These settings were reverted locally after testing because they did not reduce write frequency.

Impact:

  • The main issue is not just accumulated file size. TRACE and stream/SSE-related events continue to be persisted locally at high frequency.
  • A documented way to lower, sample, bound, rotate, or disable this SQLite runtime log stream would be preferable to local schema hacks or undocumented [feedback] settings.

Requested upstream fix:

  • Do not persist TRACE-level runtime events to SQLite in normal release builds by default.
  • Provide a documented log_level or equivalent for the SQLite runtime log stream.
  • Document retention knobs for logs_2.sqlite, if they exist.
  • Avoid requiring local trigger/schema modifications as a workaround.
aidawilliam41-ops · 1 month ago

Adding a fresh Windows data point from a newer build.

Environment:

  • Codex Desktop: 26.707.91948
  • codex-cli 0.144.5
  • Windows x64
  • Database: %USERPROFILE%\.codex\logs_2.sqlite

Read-only snapshots:

  • 2026-07-09: database 517,644,288 bytes; WAL 37,220,112 bytes.
  • 2026-07-16: database 1,046,462,464 bytes; WAL 5,051,152 bytes.
  • Database growth: +528,818,176 bytes (+102.2%) in about one week.

Rows added after the earlier snapshot cutoff:

| Level | Rows | estimated_bytes |
|---|---:|---:|
| TRACE | 560,765 | 305,029,237 |
| DEBUG | 155,850 | 106,041,789 |
| INFO | 94,391 | 56,355,741 |
| WARN | 4,699 | 2,878,563 |
| ERROR | 522 | 620,921 |

That is 816,227 new rows and about 470.9 MB of estimated payload. TRACE + DEBUG alone account for 716,615 rows and about 411 MB. No insert-blocking trigger or other SQLite mitigation was enabled.

The app remains usable, but the persistent high-volume logging clearly continues on the current Windows build.

Astel0504 · 1 month ago

Adding another Windows reproduction with read-only SQLite/WAL measurements and a reversible emergency mitigation.

Environment

  • Windows x64
  • codex-cli 0.144.4
  • Default per-user Codex log database (~/.codex/logs_2.sqlite)
  • No RUST_LOG, CODEX_LOG, OTEL_LOG_LEVEL, or OTEL_TRACES_EXPORTER value was present in the process environment.
  • No TRACE/logging/OTel override was found in config.toml.

Before mitigation

  • Main database: approximately 2.795 GB
  • WAL: 8,746,792 bytes
  • Journal mode: WAL
  • PRAGMA quick_check: ok
  • No pre-existing trigger on logs

Over a fixed 10-second interval after the initial snapshot:

  • MAX(id): +151
  • TRACE rows: +134
  • DEBUG rows: +11
  • INFO rows: +6
  • WAL size remained allocated at 8,746,792 bytes, but its modification time changed during 9 of the 10 one-second samples.

A bounded aggregate over the retained rows in the latest 100,000-ID range found:

  • TRACE: 4,616 rows
  • DEBUG: 1,224 rows
  • INFO: 530 rows
  • WARN: 86 rows
  • TRACE estimated payload: about 35.4 MB
  • 5 distinct writer process_uuid values

The leading TRACE targets included:

  • codex_api::sse::responses
  • codex_app_server::outgoing_message
  • hyper_util::client::legacy::*
  • codex_mcp::connection_manager
  • codex_tui::markdown_stream
  • codex_core::session::turn
  • codex_http_client::transport

No log message bodies, prompts, headers, tokens, or other private payloads were read or included in this report.

Emergency local mitigation

After making an online SQLite backup and verifying that backup with PRAGMA quick_check, a persistent table-wide trigger was added:

CREATE TRIGGER "codex_suppress_logs_inserts_v1"
BEFORE INSERT ON "logs"
FOR EACH ROW
BEGIN
  SELECT RAISE(IGNORE);
END;

This is an unsupported emergency workaround. It suppresses all new local diagnostic log rows, not only TRACE, and may reduce the usefulness of future /feedback diagnostic attachments. No existing rows were deleted, and no WAL/SHM file was removed, truncated, checkpointed, or vacuumed.

After mitigation

Across 16 samples over 15 seconds:

  • MAX(id) remained unchanged.
  • Highest TRACE id remained unchanged.
  • WAL size remained unchanged.
  • WAL modification time remained unchanged.
  • WAL SHA-256 remained byte-for-byte unchanged.
  • Final live PRAGMA quick_check: ok

A separate reusable read-only check repeated the same validation over 10 seconds and passed.

This reinforces that high-frequency local writes are coming from the SQLite diagnostic sink during ordinary Codex activity, and that watching only WAL size or row count can miss ongoing overwrite/prune churn. A supported upstream control for SQLite log level, sampling, retention, or disabling this sink would be much safer than schema triggers.