Skip to content

macOS Codex 26.623.61825 still persists high-frequency TRACE logs to logs_2.sqlite #30719

Description

@EarFrog

Summary

On macOS, Codex Desktop 26.623.61825 / embedded codex-cli 0.142.3 still persists high-frequency TRACE logs into the local SQLite feedback log database (~/.codex/logs_2.sqlite) and its WAL during normal use, even though the app-server process has RUST_LOG=warn.

This is not a cosmetic/UI issue. The concern is persistent diagnostic logging causing unnecessary local disk I/O, SQLite/WAL churn, and possible retention of detailed runtime data.

Related reports include #17320, #28224, #29532, #29814, and #30405. I am opening this as a fresh current-version macOS data point.

Environment

  • OS: macOS 26.5.1, arm64
  • Codex.app: 26.623.61825, build 4548
  • Embedded CLI: codex-cli 0.142.3
  • codex doctor: reports 0.142.4 available, current 0.142.3
  • App-server command: /Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled
  • App-server environment includes: RUST_LOG=warn
  • Log database: ~/.codex/logs_2.sqlite
  • SQLite journal mode: wal

Observed behavior before workaround

The active log database was already large:

logs_2.sqlite      ~406 MiB
logs_2.sqlite-wal  ~4.5 MiB

A live SQLite inspection showed a large TRACE share:

MAX(id):        41,863,047
retained rows:  381,734
TRACE rows:     289,408
non-TRACE rows:  92,326

Recent rows were dominated by TRACE logs:

Recent 5000 rows by level:
TRACE  4070
INFO    464
DEBUG   416
WARN     50

Representative recent TRACE targets were low-level protocol/dependency logs, for example:

h2::proto::streams::flow_control
h2::proto::streams::recv
h2::proto::connection
h2::codec::framed_read
log

A later aggregate over recent TRACE rows showed these targets as the largest groups:

TRACE codex_api::sse::responses                 2431
TRACE log                                       1439
TRACE codex_mcp::connection_manager              432
TRACE h2::codec::framed_read                     137
TRACE h2::proto::streams::recv                    73
TRACE h2::proto::streams::prioritize              65
TRACE h2::proto::connection                       61
TRACE codex_core::session::turn                   59
TRACE codex_api::endpoint::responses_websocket    59
TRACE codex_core::client                          55

During inspection, MAX(id) and the latest row ids continued advancing, which indicates ongoing insert churn rather than a static old database. I am not pasting raw feedback_log_body values because they may contain private session, tool, path, or protocol data.

Temporary workaround used locally

I first installed a TRACE-only trigger to confirm the source of churn:

CREATE TRIGGER ignore_trace_logs_insert
BEFORE INSERT ON logs
WHEN upper(NEW.level) = 'TRACE'
BEGIN
  SELECT RAISE(IGNORE);
END;

After that, TRACE stopped growing:

max_trace_id: 41,880,082 -> 41,880,082
WAL bytes:    4,684,472  -> 4,684,472
sample gap:   ~8 seconds

However, MAX(id) still advanced slightly from non-TRACE DEBUG/INFO inserts:

MAX(id): 41,880,426 -> 41,880,432

To stop all persistent log-table writes temporarily, I then used an all-insert trigger:

CREATE TRIGGER ignore_logs_insert
BEFORE INSERT ON logs
BEGIN
  SELECT RAISE(IGNORE);
END;

That fully stopped growth over the verification window:

MAX(id):       41,880,471 -> 41,880,471
rows:          382,004    -> 382,004
TRACE rows:    289,271    -> 289,271
max TRACE id:  41,880,082 -> 41,880,082
sqlite_seq:    41,880,471 -> 41,880,471
WAL bytes:     4,684,472  -> 4,684,472
sample gap:    ~12 seconds

This workaround is not a product fix and it disables useful local diagnostics. It only demonstrates that the persistent logs table is the write path causing the observed churn.

Expected behavior

Production Codex Desktop builds should not persist high-frequency frame-level/dependency-level TRACE logs into logs_2.sqlite by default, especially when the app-server process has RUST_LOG=warn.

Expected improvements:

  • The SQLite feedback log sink should honor the effective runtime log-level filter, or expose a separate documented persisted-log-level setting.
  • Low-value TRACE targets such as log, h2::*, websocket/SSE frame logs, and dependency internals should be suppressed, sampled, summarized, or bounded by default.
  • Local diagnostic logs should have clear size/write caps, retention/rotation, and WAL checkpoint/truncation behavior.
  • Users should have a documented way to reduce or disable persistent diagnostic logs without disabling durable Codex state.

Reproduction sketch

  1. Start Codex Desktop on macOS.
  2. Confirm the app-server process has RUST_LOG=warn.
  3. Use Codex normally in an active thread.
  4. Inspect ~/.codex/logs_2.sqlite and ~/.codex/logs_2.sqlite-wal.
  5. Sample MAX(id), row counts by level, recent targets, and WAL size/mtime over a short interval.
  6. Observe continuing TRACE-heavy inserts into the persistent SQLite log table during normal use.

Privacy note

I am intentionally not attaching logs_2.sqlite or raw log bodies. They may contain private conversation text, local paths, tool output, or protocol payload fragments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingperformance

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions