Repository navigation
macOS: Persistent SQLite TRACE target=log churn remains after rust-v0.142.0 #29532
Description
Summary
After upgrading to rust-v0.142.0, I can still reproduce persistent SQLite log churn on macOS in ~/.codex/logs_2.sqlite.
This looks like a partial fix:
#29432appears to have helped:codex_api::endpoint::responses_websocketis much lower than before.- However,
#29457does not appear to fully solve the persistent SQLite churn in this app build/runtime. The release note says noisy persistent log targets were filtered, and the PR says bridgedtarget=logevents should be excluded from the SQLite sink, butTRACE target=logis still the dominant persisted target here.
I also posted an earlier data point in the closed umbrella issue #28224 here:
Opening a new issue because #28224 is closed and this is post-rust-v0.142.0 macOS data.
Environment
- Platform: macOS 26.5.1, arm64
- Codex app:
26.616.71553, build4265 - Embedded CLI:
codex-cli 0.142.0 - PATH CLI:
codex-cli 0.142.0 - App-server process:
/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled - App-server PID/start at sample time:
7763, startedTue Jun 23 10:17:10 2026 RUST_LOG: empty~/.codex/config.toml:[analytics] enabled = false- SQLite trigger count during the sample:
0 logs_2.sqlitejournal mode:wal
No local block_log_inserts trigger was present during this sample.
Files observed
At the start of the sample:
~/.codex/logs_2.sqlite 745,517,056 bytes
~/.codex/logs_2.sqlite-wal 4,437,272 bytes
~/.codex/logs_2.sqlite-shm 32,768 bytes
The active app-server process was holding the DB/WAL/SHM files open.
Read-only 60 second sample
Sample window:
2026-06-23 10:43:00 +0800 to 2026-06-23 10:44:00 +0800
SQLite metadata before/after:
trigger_count: 0 -> 0
row_count: 200589 -> 200589
max_id: 725810463 -> 725811933
sqlite_seq: 725810463 -> 725811933
max_ts: 1782182580 -> 1782182638
So the retained row count stayed flat, but sqlite_sequence / max_id advanced by 1,470 in about 60 seconds. This looks like continued insert-and-prune churn.
File mtimes also moved during the sample:
logs_2.sqlite mtime: 1782182580 -> 1782182613
logs_2.sqlite-wal mtime: 1782182580 -> 1782182638
The WAL size stayed stable at about 4.4 MB, so file size alone hides the ongoing write activity.
Recent persisted targets
Rows in the last 60 seconds:
TRACE log 989 rows, 526.8 KiB
TRACE codex_api::sse::responses 14 rows, 14.0 KiB
TRACE codex_app_server::outgoing_message 12 rows, 2.0 KiB
TRACE codex_mcp::connection_manager 6 rows, 4.9 KiB
DEBUG codex_core::stream_events_utils 3 rows, 3.3 KiB
INFO feedback_tags 3 rows, 3.0 KiB
INFO codex_core::stream_events_utils 2 rows, 5.5 KiB
TRACE codex_api::endpoint::responses_websocket 1 row, 40.8 KiB
TRACE codex_core::session::turn 1 row, 0.9 KiB
TRACE targets in the last 5 minutes:
log 989 rows, 526.8 KiB
codex_api::sse::responses 238 rows, 239.5 KiB
codex_mcp::connection_manager 18 rows, 13.8 KiB
codex_app_server::outgoing_message 12 rows, 2.0 KiB
codex_core::session::turn 2 rows, 1.8 KiB
codex_api::endpoint::responses_websocket 2 rows, 80.0 KiB
Expected behavior
After rust-v0.142.0, Codex should not continuously persist high-frequency TRACE target=log rows into logs_2.sqlite by default, especially after #29457.
Actual behavior
Codex app-server continued to insert high-frequency TRACE target=log rows into the persistent SQLite log sink. The retained row count stayed flat, but max(id) / sqlite_sequence kept advancing and the DB/WAL mtimes kept moving, indicating ongoing insert-and-prune churn.
Privacy note
I am intentionally not pasting raw feedback_log_body contents because they may contain private conversation, local path, tool, or response data.
Activity
github-actions commentedon Jun 23, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
zyfasos commentedon Jun 23, 2026
Additional macOS reproduction on the current Codex app build.
Environment:
APPLE SSD AP0512Z), SMART statusVerified26.616.71553, build4265codex-cli 0.142.0/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled34793RUST_LOG=infowas set vialaunchctl getenv RUST_LOG, but persisted SQLite rows still includedTRACEandDEBUG.Files observed:
lsofshowed the active Codex app-server process holding open handles to the DB, WAL, and SHM files.60-second quiet sample:
This again suggests insert-and-prune churn: retained row count barely changed, but
max(id)advanced by 1,666 in about a minute.Rows visible in that sample window included:
Total visible
TRACErows in the sample window:940.The latest
TRACE target=logsamples were websocket/tungstenite noise, including:Current visible level distribution at collection time:
Impact: this creates sustained writes to the persistent SQLite log sink during normal Codex app use.
RUST_LOG=infodid not stop these persistedTRACErows, so the user-level mitigation does not appear to work for this path.I have a private evidence package with raw command output, SQLite read-only queries, file metadata, hashes, and the 60-second WAL/SQLite sample. I am not attaching raw
feedback_log_bodycontents publicly because they may include local paths, conversation IDs, command fragments, or response data.vadxq commentedon Jun 23, 2026
Please fix this as soon as possible! This issue is widespread and serious. Thank you.
lock-down commentedon Jun 23, 2026
+1 Please fix this as soon as possible! This issue is widespread and serious. Thank you.
nomideus commentedon Jun 23, 2026
Additional current-build datapoint from macOS Desktop
26.616.71553/ build4265, bundled/globalcodex-cli 0.142.0.During active Desktop use, I temporarily removed a local SQLite mitigation trigger, recorded
max(id)=707460512, waited 15 seconds, then restored the trigger. New retained rows over that window:Rows matching the previously noisy targets (
log,codex_otel.log_only,codex_otel.trace_safe,codex_api::endpoint::responses_websocket,codex_api::sse::responses) were1075in the same 15-second window.This is another confirmation that the current Desktop app-server path is still persisting high-volume TRACE
target=logrows on the shipped 0.142.0 build. The local mitigation trigger was restored after the measurement.RonZhu commentedon Jun 23, 2026
Additional macOS data point from another machine: I can still reproduce persistent SQLite TRACE churn after restarting Codex Desktop and after manually compacting the log DB.
Environment
26.616.71553, build4265codex-cli 0.142.0codex-cli 0.142.0/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabledRUST_LOGobserved in the process environment:warn~/.codex/logs_2.sqlitejournal mode observed earlier:walI am not attaching or pasting raw
feedback_log_bodyrows because they can contain private conversation/tool/local-path details.Before manual cleanup
Before compacting, the local log files were:
The table showed high churn/free space:
A 30 second sample after restarting Codex Desktop showed continued insert-and-prune activity:
Recent 2 minute target distribution during that sample was still dominated by TRACE rows:
After manual cleanup / compaction
I then retained only a small recent window of diagnostic rows and ran checkpoint/VACUUM. Integrity check returned
ok, and the files were reduced to:However, without changing anything else, Codex Desktop quickly started growing the files again. About 80 seconds later:
Rows retained in the last 5 minutes at that point:
Expected
After
rust-v0.142.0/ #29432 / #29457, the persistent SQLite sink should not continue high-frequency insert-and-prune churn dominated byTRACE target=logand related websocket/SSE targets during normal Desktop use.Actual
Even after restart and after compacting the database down to a tiny valid state, the active Desktop app-server began writing again immediately. The on-disk DB/WAL grew from about
1.8M + 0Bto about38M + 37Mwithin roughly 80 seconds, and the retained recent rows were still dominated by TRACE targets.This makes the current behavior look like an incomplete fix or a remaining Desktop-app persistent-log sink path that still persists noisy TRACE rows.
mdbecker commentedon Jun 23, 2026
I’m seeing what looks like the same underlying SQLite churn pattern on macOS, though my setup differs slightly: I have not specifically disabled analytics/plugins, and the running process is
codex app-server --analytics-default-enabled.I posted the fuller diagnostic here: #29612 (comment)
Summary of my repro:
Over a 5-minute idle sample, with Codex Desktop open in the background but not actively used:
The DB was healthy and compacted beforehand, so this did not appear to be leftover pre-fix bloat:
The exact sampled ID window showed retained rows dominated by
TRACE target=log:All retained rows from that sampled window belonged to the same app-server process.
So this looks like the same post-0.142.0 behavior: file size may remain bounded, but the app-server still continuously inserts and prunes persistent SQLite log rows while idle, mostly
TRACE target=log, despiteRUST_LOG=warn.nicksenround1 commentedon Jun 24, 2026
Additional macOS datapoint after cleanup/compaction, from another affected machine.
I can still reproduce the post-
0.142.0insert-and-prune churn after fully compacting the log DB. The historical bloat was cleaned up successfully, but the current app-server continues to persistTRACE target=logrows.Environment
The active app-server process was holding open handles to
logs_2.sqlite,logs_2.sqlite-wal, andlogs_2.sqlite-shm.Before cleanup
Before manually clearing/compacting the DB, the files had grown to:
SQLite stats at that point showed this was mostly free pages from churn:
After
DELETE FROM logs, resetting the sequence, andVACUUM, the DB compacted successfully:Repro after cleanup / restart
Immediately after cleanup and restart, rows began accumulating again, dominated by
TRACE target=log:A 20-second sample shortly after restart showed much higher active churn:
Top retained rows from that ID window:
A later quieter 30-second sample still showed the same insert-and-prune pattern with file sizes bounded:
Top retained rows from that sampled ID window:
I am intentionally not pasting raw
feedback_log_bodyvalues because they may contain private local paths, conversation, tool, or response data.User-visible impact
Before cleanup, while several Codex tasks were open at the same time, I observed frequent Codex restarts and UI lag. Cleaning/VACUUM reduced the historical DB size from ~811M to ~5.3M, but the high-frequency
TRACE target=loginsert/prune behavior is still present on the current Desktop app-server.So the remaining issue seems to be:
0.142.0reduces/bounds some file-size growth, but the shipped macOS Desktop app-server still persists high-frequencyTRACE target=logrows and continues SQLite churn even withRUST_LOG=warn.zyfasos commentedon Jun 24, 2026
Additional datapoint after updating to the newer macOS app build
26.616.81150/ build4306.Environment:
26.616.81150, build4306codex-cli 0.142.0/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled88553, startedWed Jun 24 09:20:21 2026Controlled sample with the trigger disabled:
Rows visible in the sample window:
Total
TRACErows in the 30-second window:453.The latest
TRACE target=logrows are still websocket/tungstenite noise, includingWouldBlock,tokio-tungstenite,WebSocketStream.with_context,Stream.poll_next,Received message, decompression, and<FRAME>parsing lines.So this still reproduces on app build
4306; it does not appear fully fixed by this build.Don-Quijote224 commentedon Jun 24, 2026
现在macos的codex桌面端更新到了26.622.11653,还有这个问题吗
almostlover-hao commentedon Jun 24, 2026
Additional macOS data point from Codex Desktop showing that the issue still reproduces on my machine, and that
sqlite_homeis currently the only effective local mitigation I found.Environment
diskutil: SMART StatusVerified, TRIM supported)/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabledBROWSER_USE_CODEX_APP_VERSION=26.616.81150codex-cli 0.142.0~/.codex/logs_2.sqlite~/.codex/logs_2.sqlite-wal~/.codex/state_5.sqlite-walConfig tried
~/.codex/config.tomlincluded:The restarted app-server process also inherited:
Confirmed via:
Observed behavior before mitigation
After restarting Codex Desktop with the config above, a 60-second
proc_pid_rusagesample still showed:The new app-server process had already accumulated substantial writes shortly after restart:
In an earlier active diagnostic window, app-server lifetime written bytes reached about:
Recent rows in
logs_2.sqlitestill included persisted TRACE records despiteRUST_LOG=warn:Largest recent targets included:
This confirms the SQLite feedback/log sink is still persisting TRACE-level data even when the process environment has
RUST_LOG=warnand analytics/OTel exporters are disabled.Why file size alone hides the issue
The retained DB size was not enough to estimate real write volume. The file stayed bounded while
logs_2.sqlite-waland SQLite insert/prune churn continued. This matches the pattern described in this issue: current file size can look moderate while SSD writes continue due to insert, WAL write, prune, checkpoint, and rewrite activity.Local mitigation tested
I moved only Codex's SQLite-backed runtime state to a RAM disk:
After restarting Codex Desktop,
lsofconfirmed these were all on the RAM disk:A follow-up 60-second sample still showed process-level writes:
But visible internal SSD growth for the Codex SQLite files dropped to zero because the SQLite writes were on the RAM disk:
A broader 30-second scan of likely Codex internal-SSD paths showed only tiny non-SQLite growth:
So
sqlite_hometo RAM disk mitigates SSD wear, but it does not fix the root cause. It only moves the high-frequency SQLite WAL writes away from the internal SSD.Expected fix
Please make the persistent SQLite log sink honor the same filtering as
RUST_LOG/ runtime log level, or provide a documented config option to disable persistent SQLite feedback logs or cap them aggressively. WithRUST_LOG=warn,[analytics].enabled=false, and all[otel]exporters set tonone, TRACE websocket/SSE/internaltarget=logrecords should not continue to be persisted tologs_2.sqliteduring normal desktop usage.Privacy note
I am not attaching the SQLite DB or raw
feedback_log_bodyrows because they may contain private local paths, tool output, and conversation/session details.21 remaining items
RonZhu commentedon Jul 6, 2026
Follow-up from the same affected Mac after updating to a newer Desktop build again.
Environment:
27.0(26A5368g),arm6426.623.101652, build4674codex-cli 0.142.5codex-cli 0.142.5/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled98496, startedMon Jul 6 10:49:08 2026launchctl getenv RUST_LOGreturned empty/unset during this check/Users/ron/.local/bin/codex app-server --listen stdio://, PID3728sample_log_inserts,trim_sampled_logsImportant note: this is another protected-state check, not a raw insert-rate measurement. I did not remove the local mitigation this time. On this machine those triggers retain at most about one row every 10 seconds and keep only the newest 500 retained rows.
Current retained SQLite state after the sample:
30-second protected sample:
File sizes at the end of the check:
Top retained targets after the sample:
The newest retained rows immediately after the sample were still from the active Desktop app-server process UUID:
Conclusion from this machine:
26.623.101652/ build4674/codex-cli 0.142.5still does not look fully fixed. The large websocket request-payload trace symptom may be improved, as others noted for #30771, but the broader persistent SQLite TRACE sink still appears active: retained rows remain500/500TRACE andmax_trace_idcontinues to advance under the local sampled-retention trigger.I am not pasting raw
feedback_log_bodyvalues because they may include local paths, tool output, or conversation/session details.tangleo203 commentedon Jul 10, 2026
Additional reproduction on ChatGPT-integrated Codex / 0.144.0-alpha.4
I can still reproduce the bridged
TRACE target=logpersistence on a newer macOS build that embeds Codex inside the ChatGPT app.Environment
26.707.31428(build5059)/Applications/ChatGPT.app/Contents/Resources/codexcodex-cli 0.144.0-alpha.4~/.codex/logs_2.sqliteEvidence collected before installing any local workaround
The current app-server process persisted 436 rows with
target=logbetween:Example sanitized messages included:
At the time of inspection, the retained target counts included:
No retained rows were found for
codex_otel.log_onlyorcodex_otel.trace_safe, so that part of the filtering appears effective. However, bridgedtarget=logevents are still reaching SQLite, despite #29599 being intended to reject them inside the sink.This appears to be either:
metadata.target() == "log"guard.Local confirmation/workaround
After the measurement, I installed a SQLite
BEFORE INSERT ... RAISE(IGNORE)trigger for the noisy targets. A test insert was ignored, and normal non-blocked log IDs continued advancing while the blocked-target maximum ID stayed unchanged. This is only a local workaround; filtering before formatting/queueing remains preferable.Raw payloads, thread IDs, local paths, and conversation contents are intentionally omitted.
RonZhu commentedon Jul 13, 2026
Follow-up from the same affected Mac after updating to the newer ChatGPT-integrated Codex build.
Environment:
27.0(26A5378j),arm6426.707.61608, build5200/Applications/ChatGPT.app/Contents/Resources/codexcodex-cli 0.144.0-alpha.4command -v codexnow resolves to the ChatGPT embedded binary on this machine/Applications/Codex.app/Contents/Resources/codexbinary was not present during this check/Applications/ChatGPT.app/Contents/Resources/codex -c features.code_mode_host=true app-server --analytics-default-enabled92069, startedMon Jul 13 10:03:30 2026~/.local/bin/codex app-server --listen stdio://, PID89531launchctl getenv RUST_LOGreturned empty/unset during this checksample_log_inserts,trim_sampled_logsImportant note: this is another protected-state check, not a raw insert-rate measurement. I did not remove the local mitigation this time. On this machine those triggers retain at most about one row every 10 seconds and keep only the newest 500 retained rows.
Current retained SQLite state after the sample:
30-second protected sample:
File sizes at the end of the check:
Top retained targets after the sample:
The newest retained rows immediately after the sample included new TRACE rows from both the ChatGPT-integrated app-server and the stdio app-server:
Conclusion from this machine: the old
500/500 TRACEprotected-state symptom has changed in the ChatGPT-integrated0.144.0-alpha.4build: retained rows now include DEBUG/INFO/WARN as well. However, the broader issue still does not look fully fixed here.max_trace_idcontinued to advance during the protected sample, andTRACE target=logremains the largest retained target. This matches the concern in the newer ChatGPT-integrated reports: part of the older filtering appears improved, but bridged TRACE/log-style events still reach the persistent SQLite DB.I am not pasting raw
feedback_log_bodyvalues because they may include local paths, tool output, or conversation/session details.0xdevalias commentedon Jul 13, 2026
Freyliu0516 commentedon Jul 14, 2026
I’ve completed an independent reference implementation and validation effort for the persistent SQLite TRACE/DEBUG issue described here.
Repository:
https://github.com/Freyliu0516/Codex-Log-Doctor
Proposed upstream change
The upstream patch is deliberately small and separate from the user-side diagnostic tool:
TRACEtoWARN;Reference patch:
https://github.com/Freyliu0516/Codex-Log-Doctor/tree/main/upstream
The independent tool does not patch or replace an installed Codex binary. The
upstream/directory exists only as a reviewable reference implementation.Validation
The patched Codex source was tested against the pinned upstream base:
codex-stateprimary tests: 151 passed;binary tests: 3 passed;
doctests: 1 passed;
persistence regression:
The separate Codex Log Doctor repository also passed:
The repository additionally contains 18 deterministic component and failure-mode scenarios covering SQLite/WAL contention, queue saturation, backup and rollback, interrupted operations, unsupported schemas, and report redaction. These are supporting tests, not a claim that all 18 scenarios exercise the complete Codex app-server pipeline.
Public CI evidence is linked from the merged initial implementation PR:
Freyliu0516/Codex-Log-Doctor#1
User-side mitigation
The tool can install a fingerprint-gated SQLite
BEFORE INSERTtrigger that rejects TRACE rows. It requires:--apply;This is intended only as a reversible workaround. It reduces retained TRACE rows,
MAX(id)growth, WAL writes, indexing, and subsequent pruning, but it does not eliminate upstream event construction, formatting, queueing, transactions, or attempted INSERT execution.Early filtering in Codex remains the preferred fix.
Request
Would the Codex team be open to reviewing the persistence-filter approach?
If changing the persistent SQLite default from TRACE to WARN is consistent with the intended feedback and diagnostics behavior, I would appreciate guidance on whether the team would invite a focused upstream PR limited to:
codex-rs/state/src/log_db.rs;I’m also happy to adjust the proposed target-specific policy if there are operational events that the feedback pipeline must continue retaining below WARN.
fujiwarakasei commentedon Jul 15, 2026
I can still reproduce significant persistent SQLite TRACE churn on the current ChatGPT-integrated Codex desktop build, and I think this deserves clarification after #28224 was closed.
Environment
/Applications/ChatGPT.app26.707.722215307codex-cli 0.144.2~/.codex/logs_2.sqliteCODEX_HOMEDBs such asclient-hub-codex-home/logs_2.sqliteControlled test
I had been using a local SQLite stopgap trigger:
With the trigger enabled, short samples show:
id_delta=0count_delta=0I then temporarily removed the trigger for a controlled test and restored it immediately afterward.
Result: within roughly a one-minute active Codex window, the global
~/.codex/logs_2.sqliteaccumulated about 2.6k rows and the WAL grew to about 4.15 MiB.Dominant persisted targets were still TRACE/DEBUG-style internal plumbing:
TRACE codex_api::sse::responsesTRACE codex_mcp::connection_managerTRACE codex_app_server::outgoing_messageTRACE hyper_util::client::legacy::*DEBUG codex_core::stream_events_utilsAfter restoring the trigger, another short sample returned to:
id_delta=0count_delta=0Why I am posting
#28224 was closed as fixed, but the current shipping desktop app on my machine still bundles
codex-cli 0.144.2. From the discussion around #28224, it sounds like the more relevant logging fixes (#31789, #31790, #31791, #31792) are expected in the0.145.0-alpha.4+line, not necessarily in this bundled desktop version.So I would like to clarify:
block_log_insertsuntil the bundled desktop CLI reaches the fixed line?I would also encourage other affected users to share comparable measurements with:
MAX(id)deltafriday-james commentedon Jul 16, 2026
Fresh measurements on codex-cli 0.144.3 (Linux/ext4), plus a minimal tested patch and an A/B benchmark. TL;DR: most of the remaining churn is flush policy, not log content — batching the sink by bytes/severity instead of every 2 s cuts its physical writes ~5x on a steady-state workload, down to SQLite's WAL+checkpoint double-write floor, with zero change to what
/feedbacksees.Measurements: the writes are flush overhead, not content
Four resumed TUI sessions left idle; write rates from
/proc/<pid>/iodeltas, content attribution from queryinglogs_2.sqlite(read-only) for rows inserted inside the same instrumented window:The DB itself stays at ~25 MB — retention caps work. The wear comes from the durability policy:
LOG_FLUSH_INTERVAL = 2smeans ~43,000 transactions/day/process, each paying WAL page images + (at retention-cap steady state, which every long-lived session reaches) the windowed prune DELETE inside the same transaction.Row-level attribution also shows why target muting (#29457, #29599, #31789, #31791) can't converge: after accounting for those mutes, idle traffic is dominated by codex's own targets —
codex_app_server::outgoing_message(TRACE),codex_api::sse::responses(TRACE),codex_core::stream_events_utils(DEBUG),feedback_tags(INFO). Muting those defeats/feedback; keeping them keeps the churn. The reasoning that closed #23275 ("bounding individual call sites is brittle and misses future tracing events") applies equally to per-target filters.Patch: flush by bytes/severity/60 s instead of every 2 s
Branch: https://github.com/friday-james/codex-1/tree/fix/log-db-write-churn — 3 files, +127/−9, mostly tests.
/feedbackalready callslog_db.flush().awaitbefore reading (feedback_processor.rs), so feedback content is byte-identical, even mid-session.LogEntry::estimated_bytes()is factored out and shared by the sink buffer and the insert path, so the write-side threshold and partition budgets agree.A/B benchmark (each phase an isolated process)
Harness: https://github.com/friday-james/codex-1/tree/bench/log-db-write-churn (
state/examples/write_churn_bench.rs). It replays the measured idle profile — 5.3 rows/s, ~1.2 KiB/row, thread partition pre-filled past its retention cap (steady state of a long-lived session) — for 3 minutes per policy, measuring/proc/self/iowrite_bytes. Two runs, results identical to ±0.2%:The new policy's 2.9 MB against 1.17 MB of raw content is SQLite's WAL-then-checkpoint double write plus prune/B-tree overhead — i.e. the patch removes nearly all removable churn; going lower requires persisting less content or relaxing durability guarantees. Note the benchmark is single-process and therefore conservative: live sessions share one
logs_2.sqliteacross processes, where checkpoint contention pushes the old policy 2–3x higher than the bench (and in the limit produces the unbounded-WAL growth reported in #28997).Happy to open this as a PR per the invitation policy in contributing.md, or the approach is free to take as-is. Two further options if there's interest: prune hysteresis (once a partition crosses its cap, delete down to ~75% so steady-state inserts don't re-run the windowed DELETE every batch), and honoring an env override for the sink filter, which several reports expected
RUST_LOGto do (#29463, #31111).cc @jif-oai @charley-oai
papperrollinggery commentedon Jul 16, 2026
Request for clarification: current shipping build still lacks the broader SQLite fix
Following up with the current shipping macOS build:
26.707.91948, build5440codex-cli 0.144.5codex-cli 0.144.30.144.5The
rust-v0.144.5release contains only the dangerous-command detection fix in #33455. Its persistent log filter still uses:Source: https://github.com/openai/codex/blob/rust-v0.144.5/codex-rs/state/src/log_db.rs
The
0.144.4...0.144.5release comparison also does not include #31789, #31790, #31791, or #31792. This appears inconsistent with the statement in #28224 that the series of fixes was already in the latest shipping desktop app, CLI, and IDE extension.My local SQLite database is currently protected by this reversible stopgap:
Protected-state verification on the current build shows
rows=0,seq=0, andmax(id)=0. I did not remove the trigger for another raw sample because the shipping0.144.5source contains no relevant persistent-log change. I am not posting any rawfeedback_log_bodyvalues because they may contain private paths, command fragments, tool output, or conversation context.Could the maintainers please clarify:
LevelFilter::TRACEstill the intended production default for the persistent SQLite feedback log?BEFORE INSERT ... RAISE(IGNORE)trigger?/feedbackdiagnostics?A version-specific answer would help users know when it is safe to remove the trigger and restore normal persistent diagnostic logging.
RonZhu commentedon Jul 20, 2026
Follow-up after updating this Mac to the current ChatGPT-integrated Codex build.
Environment now:
27.0(26A5378n), Apple Silicon /arm64/Applications/ChatGPT.app26.715.31925, build5551codexresolves to:/Applications/ChatGPT.app/Contents/Resources/codexcodex-cli 0.145.0-alpha.18/Applications/Codex.appis not present on this machineRUST_LOGis unsetI kept the local SQLite mitigation in place for this check. The active triggers are still:
So this is a protected-state verification only; I did not remove the mitigation for another raw write-churn sample, and I am not posting raw
feedback_log_bodyvalues publicly.Current protected-state sample from
~/.codex/logs_2.sqlite:30-second retained-row sample with the mitigation still enabled:
Newest retained rows in that sample were
DEBUG codex_http_client::default_clientandINFO codex_http_client::custom_ca; the newest retained TRACE row stayed at id240689(TRACE codex_app_server::message_processor). The retained sample still includes TRACE entries fromcodex_app_server::message_processor,codex_api::sse::responses, andcodex_app_server::outgoing_message, but I cannot infer the unmitigated raw insert rate from this protected sample.Given #4988716077 and #4989141674, this updated app/CLI datapoint may help separate two questions:
A version-specific maintainer answer would still be useful: is
26.715.31925/ build5551/codex-cli 0.145.0-alpha.18expected to be safe enough for affected users to remove local SQLite mitigations, or should users keep them until a stable desktop/CLI release with an explicit persistent-log fix ships?TheJhyeFactor commentedon Jul 20, 2026
Hey, I had a look at this.
The SQLite sink already has a guard that drops bridged events with the
logtarget before they reach the queue. The missing piece was a test that proves the guard still works when the outer tracing filter is permissive, which is the path that allowed this noise through in the first place.I've added that regression test. It sends a bridged
target="log"event alongside a normal Codex state event, flushes the sink, and checks that only the normal event was written to SQLite.Branch: https://github.com/TheJhyeFactor/codex/tree/fix/sqlite-log-bridge-regression-29532
I ran
CARGO_NET_OFFLINE=true cargo test -p codex-statelocally on macOS. All 153 unit tests, 3 binary tests, and 1 doctest passed.I couldn't open the PR because GitHub returned a
CreatePullRequestpermission error for my account, so I've linked the tested branch here for review.RonZhu commentedon Jul 23, 2026
Follow-up after another ChatGPT-integrated Codex update on the same Mac.
Environment now:
26.715.72359, build5718codex-cli 0.145.0-alpha.30codexstill resolves through/Applications/ChatGPT.app/Contents/Resources/codex/Applications/Codex.appis still not presentRUST_LOGis unsetI kept the local SQLite mitigation enabled for this check, so this is still only a protected-state verification. I did not remove the mitigation for an unbounded raw write-churn sample, and I am not posting raw
feedback_log_bodyvalues or detailed local SQLite metadata publicly.Qualitatively, in the protected sample I no longer see bridged
TRACE target=logamong the newest/top retained entries, which seems consistent with the regression-test discussion in #5018554274. However, normal Codex TRACE targets are still present in the retained sample, and this protected check cannot answer the broader SQLite sink write/flush-policy question raised in #4988716077.Could maintainers clarify two version-specific points for affected users?
26.715.72359/ build5718/codex-cli 0.145.0-alpha.30expected to contain the relevant macOS persistent-log target filtering fix?bbingz commentedon Jul 24, 2026
Analysis (community)
Thanks for tracking this — attempting a residual-focused analysis aligned with docs/contributing.md (invitation-only: analysis in-thread, no unsolicited PR).
logs_2.sqlite SSD)Observed (from issue + public residual signal)
Summary After upgrading to
rust-v0.142.0, I can still reproduce persistent SQLite log churn on macOS in~/.codex/logs_2.sqlite. This looks like a partial fix: -#29432appears to have helped:codex_api::endpoint::responses_websocketis much lower than before. - However,#29457does not appear to fully solve the persistent SQLite churn in this app build/runtime. The release note says noisy persistent log targets were filtered, and the PR says bridgedtarget=logevents should be excLocal residual measurement (2026-07-24, this reporter)
On a host running codex-cli 0.146.0-alpha.6 (newer than 0.142–0.145 residual reports):
Signal-14 INTERIM evidence (from qwen_s14 mid-flight)
captured: 2026-07-24T15:10:05Z
/Users/bing/.codex/logs_2.sqlitesize=1778548736 mtime=Fri Jul 24 23:09:38 2026/Users/bing/.codex/logs_2.sqlite-walsize=30405632 mtime=Fri Jul 24 23:10:04 2026codex-cli 0.146.0-alpha.6level counts (ro)
rows/max_ts: 137106|2026-07-24 23:10:05
This is not a claim that every install still burns TB/year — it is a version-pinned observation that TRACE still lands in the SQLite sink after the #28224-era mitigations on a current alpha, consistent with residual issues still open.
Root-cause hypothesis (to be confirmed on
main)logs_2.sqlite.High-level fix outline (not a PR)
RUST_LOG/ app log level end-to-end into the SQLite writer.Tests
Questions for maintainers
Happy to refine with more measurements or code pointers. No unsolicited PR from me.
bbingz commentedon Jul 24, 2026
Analysis (community)
Residual analysis for #29532 (TRACE churn remains after rust-v0.142+ claims) — invitation-only under docs/contributing.md. No unsolicited PR.
Distinct from #17320 (default TRACE policy) and #28997 (WAL budget): this thread is about fix claims vs still-shipping residual on current builds.
Deterministic evidence (code + runtime)
Code (
5dd992acd3):codex-rs/state/src/log_db.rsdefault_filter():.with_default(LevelFilter::TRACE)(L55)hyper_util→WARN,log→OFF, a fewcodex_otel*/codex_api::responses_websocket_timingOFF,rmcp::service→INFO)LogDbLayer::on_event.codex-rs/state/src/log_db_filter_tests.rsstill document TRACE retention for non-filtered targets.Runtime (
codex-cli 0.146.0-alpha.6):logs_2.sqlite≈ 1778548736 bytes; TRACE rows 94907 of ≈137150 total.codex_api::sse::responses→ 37252codex_app_server::outgoing_message→ 19558codex_tui::markdown_stream→ 15085Root-cause hypothesis
Partial target denylists / “we fixed TRACE spam” claims did not change the default LevelFilter::TRACE for the SQLite sink, nor demote the highest-volume first-party streaming targets. Users on 0.146.x still observe multi-GB DBs and TRACE-dominant histograms.
High-level fix outline (not a PR)
codex_api::sse::responses,codex_tui::markdown_stream,codex_app_server::outgoing_message) even if global default stays DEBUG.Questions for maintainers
No unsolicited PR from me.
rellaqaq commentedon Aug 14, 2026
Additional current-stable reproduction and bounded mitigation result (2026-08-15):
codex-cli 0.147.0, persistent app-server.pwrite, WAL checkpoint, andfsync. A second current-version report records 2,147.49 MB over 44,782 seconds (47.95 KB/s).rust-v0.147.0still shows the dedicated log DB using its own default TRACE filter. The current documented configuration has no setting that independently raises or disables this SQLite sink;RUST_LOGcontrols a different layer.As a local stop-loss only, after stopping and independently verifying zero Codex handles on the DB/WAL/SHM, I installed one persistent
BEFORE INSERTtrigger on the dedicatedlogstable. It usesRAISE(IGNORE)only whenupper(NEW.level) IN ('TRACE', 'DEBUG'); INFO/WARN/ERROR and all existing rows remain intact. No database was deleted, truncated, vacuumed, checkpointed, relocated, or read for content. Rollback is the exact namedDROP TRIGGERoperation.An isolated truth-table/rollback test and live schema plus
quick_checkacceptance passed. After restart through the official managed daemon, a representative 30-second active sample wrote 217,088 bytes (7.24 KB/s), below the smaller report's 24.86 KB/s threshold and materially below both red rates. WAL metadata still changes because higher-severity diagnostics remain enabled.This is not presented as an upstream fix or maintainer-endorsed workaround. It may disappear after a DB migration/recreation. A supported persisted log-level control (or an INFO-or-higher sink default), with migration behavior documented, would remove the need for this schema-level containment.