Desktop should bound and compact logs_2.sqlite before it becomes recovery pressure

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

Summary

Codex Desktop needs a bounded local log DB lifecycle before large logs_2.sqlite files become app-server/renderer recovery pressure. The immediate renderer freeze I investigated had a local ~/.codex/logs_2.sqlite around 952 MB.

There are already several issues about TRACE rows and SQLite growth. This issue is specifically about the recovery/user-impact invariant: a large local diagnostic DB should not make the Desktop UI repeatedly freeze or require users to manually delete SQLite files to recover.

Local evidence

On the affected macOS profile:

~/.codex/logs_2.sqlite  ~952 MB
~/.codex/state_5.sqlite ~6.4 MB

The Desktop app-server and bridge/helper processes were still alive while the renderer was the problematic process. That suggests two interacting pressures:

  1. the renderer receives too many live events during active streaming/tool turns;
  2. persisted local log/state databases remain large across restarts, so quitting/reopening does not necessarily remove the pressure.

Raw log rows are intentionally not included because local logs can contain private paths and session content.

Problem

Even if retention/checkpointing exists, the current behavior still allows a normal Desktop profile to reach a very large local log DB. Once that happens, the failure mode is sticky:

  • relaunching the app can reuse the same large local DB;
  • app-server startup/recovery may contend on or scan local SQLite state;
  • renderer recovery or diagnostics can be affected by the same persisted state;
  • users do not get a clear safe-mode or repair path.

Suggested fix

Add an explicit bounded log lifecycle for Desktop profiles:

  • do not persist TRACE logs by default unless an explicit debug flag is enabled;
  • enforce a byte and row cap for logs_2.sqlite, not just age-based retention;
  • checkpoint/truncate WAL under normal multi-process Desktop usage;
  • run maintenance before hot startup/resume paths that can affect renderer responsiveness;
  • if the DB exceeds a safety threshold, show a repair/safe-mode path instead of letting the renderer freeze;
  • separate renderer-critical state from diagnostic logs so the UI does not depend on reading or reconciling an oversized log store;
  • expose a supported command such as codex logs compact or automatic profile maintenance.

Expected behavior

A Desktop profile should recover cleanly even if its log DB is large. Users should not need to discover and manually delete ~/.codex/logs_2.sqlite* to restore responsiveness.

Related issues

This overlaps with, but does not fully replace:

  • #30322
  • #24275
  • #27741
  • #29532
  • #30162
  • #30405
  • #25779

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 2 months ago

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

  • #29674
  • #30405
  • #29177
  • #28997
  • #29237

Powered by Codex Action

wgu9 · 2 months ago

This still looks like the right umbrella issue for the log lifecycle policy, with #30517 as the CLI startup symptom.

From current main (ccdfb4f), the relevant owner is the shared state runtime rather than Desktop-only code:

  • codex_state::LOGS_DB_FILENAME is logs_2.sqlite
  • StateRuntime::init_inner() opens/migrates the logs DB alongside state/goals/memories DBs
  • run_logs_startup_maintenance() deletes rows older than retention and then runs PRAGMA wal_checkpoint(PASSIVE)
  • foreground logging writes are buffered through the background log_db layer, but DB open and startup maintenance can still affect first-run/startup behavior

The policy I would expect from this issue:

  • diagnostic logs must be bounded independent of renderer-critical state
  • startup/reconnect should not synchronously compact/checkpoint logs on the hot path
  • size limits should include logs_2.sqlite-wal, not just retained rows in logs_2.sqlite
  • codex doctor or a safe-mode startup path should report log DB/WAL size and checkpoint health
  • there should be a manual recovery command such as codex logs compact or equivalent, so users do not need to manipulate SQLite files directly
  • if checkpoint/compact is busy, Desktop should continue with logging degraded or delayed rather than blocking app recovery

That keeps #30431 as the shared invariant, while #30517 can validate the specific “large/busy WAL stalls CLI prompt” case.

Gladiyd · 1 month ago

Additional Windows confirmation on Codex CLI 0.144.1 / Desktop 26.707.3748: the live log SQLite family currently totals 477.05 MiB, with the largest database at 463.55 MiB. No manual deletion, VACUUM, or live compaction was attempted because there is no documented supported maintenance path. A supported size metric, warning threshold, byte/row cap, and safe compact command would prevent operators from improvising against a live database. No raw rows or private paths are included.

d-w-d · 1 month ago

Here is a summary of related issues bogging down the VSCode extension (assessed and composed by GPT 5.6 Sol Ultra):

Linux ARM64 / VS Code confirmation

  • Extension: 26.707.31428
  • Bundled CLI: 0.144.0-alpha.4
  • Environment: Linux ARM64 devcontainer with persistent CODEX_HOME

The extension repeatedly failed to load, although app-server initialized normally and logged no panic, migration, authentication, or SQLite error. All quarantined databases passed PRAGMA quick_check.

logs_2.sqlite had processed 2.94 million inserts while retaining only 1,752 rows. Its pages were 91.6% free, its WAL was 8.8 MB, and roughly 84% of retained rows were dependency TRACE events, despite RUST_LOG=warn.

Quarantining the SQLite files and reinstalling the extension restored operation, although both changes occurred together. A fresh log database then resumed rapid growth, reaching a 4.3 MB WAL within roughly ten minutes.

This appears to be a valid-but-pathological logging database that bypasses corruption recovery and leaves the extension looking healthy to telemetry while being unusable to the user.