Codex Desktop becomes unusable on long active threads due to app-server/renderer memory and TRACE log churn

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

Summary

Codex Desktop becomes nearly unusable with long-running active threads, even after compaction-aware local transcript pruning.

The slowdown appears to come from the Codex app-server and renderer repeatedly handling large hot conversation state and logging large websocket/SSE response frames into logs_2.sqlite.

Environment

  • Codex Desktop: 26.429.30905
  • Electron: 41.2.0
  • macOS: 26.0.1 (25A362)
  • Machine memory: 16 GB

Observed behavior

During the slowdown:

  • codex app-server spiked to ~64% CPU.
  • codex app-server sampled physical footprint peaked at ~4.4 GB.
  • A Codex renderer reached ~1.07 GB RSS.
  • logs_2.sqlite / WAL grew by about 1.4 MB in one second.
  • Recent log rows were dominated by TRACE entries from:
  • codex_api::endpoint::responses_websocket
  • codex_api::sse::responses
  • raw-ish response/frame logging such as response.completed / received websocket frames
  • One active long-running thread had grown back to ~839 MB with 22 compactions.
  • The app remained sluggish even after pruning older pre-compaction rollout records, until restart/reload.

Chronicle was not the active CPU source in this case.

Why this seems like a Codex Desktop issue

Compaction-aware pruning helps reduce hot rollout JSONL size, but the running Desktop app still appears to keep or reconstruct very large hot thread state in app-server/renderer memory.

Separately, TRACE logging of large websocket/SSE frames can make logs_2.sqlite churn quickly, which seems to amplify the slowdown.

This makes long-running "main" threads effectively degrade over time, even when compactions exist and old raw history has been pruned locally.

Expected behavior

Long-running threads should remain usable after compaction. Codex Desktop should not need manual JSONL pruning, log rotation, or full restart to recover basic responsiveness.

Suggested fixes

  • Truncate or disable large TRACE websocket/SSE payload logging in normal Desktop builds.
  • Avoid retaining/rendering full hot thread state after compaction.
  • Lazy-load old transcript/UI history instead of materializing the whole active thread.
  • Add a first-class local "prune/compact UI history" action that preserves agent-visible compacted context.
  • Release app-server/renderer in-memory thread state after compaction/pruning without requiring a full app restart.
  • Add diagnostics that show which active thread/log source is causing app-server or renderer pressure.

Impact

For users who keep long-running main threads open, Codex Desktop can become almost unusable: high CPU, high renderer/app-server memory, heavy SQLite log churn, and severe UI lag.

View original on GitHub ↗

10 Comments

github-actions[bot] contributor · 2 months ago

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

  • #21007
  • #20269
  • #20867
  • #20781

Powered by Codex Action

baron · 2 months ago

Someone investigated this in #21211 You can improve performance just by truncating titles to 120 chars in state_5.sqlite but the sidebar still loads the full first message just on launch so it's still problematic.

Amasun93 · 1 month ago

Adding another Windows Desktop data point that matches this issue.

Environment:

  • Codex Desktop for Windows: OpenAI.Codex_26.527.3686.0_x64__2p2nqsd0c76g0
  • Codex home: %USERPROFILE%\.codex
  • Main symptom: local UI jank rather than model/network latency. Sending a prompt can make the mouse/UI stutter, and switching conversations/clicking around the UI can freeze briefly.

Observed local DB state while the app was running:

  • logs_2.sqlite: ~812.9 MB
  • logs_2.sqlite-wal: grew to ~100 MB before checkpoint; after one successful checkpoint it dropped briefly, then grew back to ~75.7 MB during continued use
  • logs rows: ~180,537
  • state_5.sqlite: ~4.36 MB
  • SQLite freelist in logs_2.sqlite: ~115,943 pages, about ~452.9 MB reclaimable/free pages

Top log targets by estimated bytes:

  • codex_api::endpoint::responses_websocket: ~101 MB / ~23k rows
  • codex_otel.log_only: ~33 MB / ~26k rows
  • codex_otel.trace_safe: ~29 MB / ~24k rows
  • codex_client::transport: ~24 MB

Experiment:

  • Running PRAGMA wal_checkpoint(PASSIVE) followed by PRAGMA wal_checkpoint(TRUNCATE) on logs_2.sqlite while Codex Desktop was open immediately reduced the perceived UI jank.
  • The main DB remained large/fragmented, so this is only a temporary mitigation; the WAL started growing again during normal use.

This makes the issue feel like normal Desktop interaction is being affected by log DB/WAL growth and SQLite churn, not just long model latency. A built-in safe action such as "Optimize local data" / "Clear local diagnostic logs", plus automatic log rotation/checkpointing or bounded TRACE logging, would likely help users recover without manually touching SQLite files.

riyadist · 1 month ago

same issue

andrewkangkr · 1 month ago

Another data point from Codex Desktop 0.140-alpha on Windows 11:

  • logs_2.sqlite reached 3.4 GB over 11 days (matches the ~10-day retention; rows pruned logically but no VACUUM, so disk stays allocated).
  • Level split: TRACE 1.2 GB (target responses_websocket alone ~1 GB), INFO 354 MB, DEBUG 57 MB. Consistent with #17320 (SQLite sink ignoring RUST_LOG).
  • A stale codex app-server process kept the WAL open after the GUI was closed (related: #22444). Killing the orphans was required before the file could be moved.
  • Amplifier: the .codex/skills file watcher fired continuously on __pycache__ (.pyc temp files) and bundled-plugin cache churn — each event logged skills cache cleared + a skills/changed app-server event at TRACE, inflating the DB further.

Mitigations that restored the app: kill orphan app-servers, move the oversized logs_2.sqlite aside (app recreates an empty one), clear stray __pycache__. A config/env knob to cap or disable the SQLite TRACE sink would help a lot.

huangdijia · 25 days ago

Adding a fresh macOS data point from a current Desktop build. This looks like the same class of issue, but with both renderer CPU and app-server TRACE/log/MCP churn visible at the same time.

Environment

  • Codex Desktop: 26.616.81150 (CFBundleVersion 4306)
  • Codex Framework / renderer helper: 149.0.7827.115
  • Codex CLI bundled resource: codex-cli 0.142.0
  • OS: macOS 27.0 (26A5368g) on arm64
  • App-server command: /Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled

Observed CPU

While the app was sluggish, repeated ps samples showed:

Codex main process                 ~20-23% CPU
codex app-server                   ~28-34% CPU
Codex Helper (Renderer)            ~105-138% CPU

Earlier samples in the same run showed the renderer around 80-151% CPU and app-server around 18-25% CPU.

The renderer was the largest CPU consumer, but the app-server was also continuously active.

logs_2.sqlite churn

Local log DB state:

~/.codex/logs_2.sqlite      2.8G
~/.codex/logs_2.sqlite-wal   10M
~/.codex/state_5.sqlite      92M
~/.codex/state_5.sqlite-wal 4.9M

Short interval sample:

logs_seq_before=195942787
logs_seq_after=195946598
logs_seq_delta=3811 over 10 seconds

That is about 381 log inserts/sec, while the app was still running normally from the user's perspective.

Recent log rows were dominated by TRACE/DEBUG/WARN entries like:

TRACE codex_mcp::connection_manager
TRACE codex_api::sse::responses
TRACE codex_rollout::recorder
TRACE codex_app_server::message_processor
TRACE codex_api::endpoint::responses_websocket
TRACE rmcp::service
TRACE tokio-tungstenite internals:
  Stream.poll_next
  WebSocketStream.with_context
  WouldBlock
  Opcode: Data(Text)
  Masked: false
DEBUG codex_config::loader::macos
DEBUG codex_config::loader::layer_io
WARN codex_features

Top recent rows by target/body included repeated session_loop{...}:submission_dispatch{...} entries under codex_mcp::connection_manager and codex_api::sse::responses.

MCP process multiplication

At the same time, the app-server had multiple repeated direct child process groups. Sanitized count:

10  node ./mcp/server.mjs
 5  npm exec xcodebuildmcp@latest mcp
 5  npm exec chrome-devtools-mcp@latest
 5  npm exec @upstash/context7-mcp --api-key <redacted>
 5  node ./mcp/server.mjs --stdio
 5  node ./mcp/server.cjs --stdio
 5  node ./mcp/server.bundle.mjs
 5  uv tool uvx mcp-server-tapd
 5  Pencil MCP server
 5  node_repl
 4  SkyComputerUseClient mcp

Most of these children were individually low CPU, but app-server was still spending CPU managing/logging the aggregate connection/event stream.

Samples

sample on the renderer for 5 seconds:

  • Physical footprint: 329.9M
  • Physical footprint peak: 726.0M
  • Hot path was the Electron/V8 renderer main thread, with stack activity in V8/JS serialization/allocation paths.

sample on app-server for 5 seconds:

  • Physical footprint: 267.7M
  • Physical footprint peak: 278.2M
  • Visible stack activity included:
  • tokio worker threads
  • sqlx-sqlite-worker-*
  • sqlite3_step
  • sqlite3_wal_checkpoint_v2
  • tracing_core::event::Event::dispatch
  • codex_state::log_db::MessageVisitor
  • codex_protocol::dynamic_tools::normalize_dynamic_tool_specs
  • tokio::fs::file::File::poll_read

Why this seems related

This looks like a combined feedback loop:

  1. The Desktop app resumes/uses active threads and MCP servers.
  2. Multiple MCP/tool processes are active or duplicated.
  3. app-server emits high-volume TRACE/SSE/MCP/log DB rows.
  4. SQLite workers and WAL/checkpoint work keep app-server busy.
  5. The renderer is also hot, apparently processing/rendering the resulting thread/event state.

The external MCP children themselves were not the primary CPU source.

Expected behavior

Codex Desktop should not sustain 100%+ renderer CPU plus 30% app-server CPU while tool subprocesses are mostly idle. TRACE logging and MCP status/event streams should be bounded, filtered, batched, or deduplicated so that normal Desktop use does not continuously drive hundreds of SQLite log inserts per second.

Related

This also overlaps with the SQLite TRACE churn tracked in #28224 and related follow-ups, but the user-visible symptom here is Desktop CPU/UI pressure with renderer + app-server both hot on 26.616.81150.

adzcsx2 · 8 days ago

I can reproduce what appears to be the same issue on Windows, and I isolated logs_2.sqlite as the trigger with a local A/B test.

Environment

  • Codex Desktop package: OpenAI.Codex_26.707.3748.0_x64
  • Codex CLI/app-server bundle: codex-cli 0.140.0
  • OS: Windows 11 Enterprise 23H2, build 22631.5768, x64
  • CPU: 12th Gen Intel Core i5-12600KF
  • RAM: 31.8 GB

Symptoms

Creating a new task, switching tasks, or opening a history item that had not yet been opened would freeze the Codex UI for several seconds. During the worst reproductions, the stall also made the rest of the Windows desktop feel temporarily unresponsive. Restarting Codex or rebooting Windows did not resolve it.

I also tested disabling Browser/Chrome integrations, plugins/MCP servers, Figma, and node_repl, and tested with a clean Electron UI profile. Those changes did not resolve the stall. Moving most session history was also not the decisive factor.

Isolated result

The local diagnostic log database had grown to:

  • logs_2.sqlite: 220.23 MB
  • logs_2.sqlite-wal: approximately 5.63 MB at the captured point

After moving the 220 MB logs_2.sqlite out of CODEX_HOME and allowing Codex to create a fresh log database, the task/window switching stalls disappeared immediately. Restoring normal Codex features did not bring the stalls back.

This is notable because the problem occurred at roughly 220 MB, substantially below the ~813 MB database reported in the original issue. It suggests the trigger may depend on fragmentation, row count, checkpoint behavior, or local SQLite contention rather than file size alone.

Temporary workaround that worked locally

  1. Fully quit Codex and its background processes.
  2. Back up/move, rather than permanently delete, the logs_2.sqlite* files from CODEX_HOME (%USERPROFILE%\.codex by default).
  3. Relaunch Codex and allow it to create a fresh diagnostic log database.

This did not remove conversation/session history in my test. I am not attaching the original SQLite database because diagnostic logs may contain private local paths, commands, or task data.

A built-in Clear/Rotate diagnostic logs or Optimize local data action, plus bounded retention and automatic WAL checkpoint/VACUUM behavior, would prevent users from needing to manipulate SQLite files manually.

devansh-jain-18 · 4 days ago

I’m seeing a closely matching slowdown on Codex Desktop for macOS and collected read-only local diagnostics.

Environment:

  • Codex Desktop: 26.707.91948 (build 5440)
  • Embedded Codex CLI: 0.144.4
  • macOS: 26.5.2 (Apple Silicon)
  • Memory: 24 GB

Observed while the UI felt sluggish:

  • Active renderer RSS: ~855 MB
  • Renderer physical footprint during a 3-second sample: ~955 MB, with a recorded peak of ~3.3 GB
  • Renderer main thread was in V8/JavaScript execution with substantial GC/finalizer activity
  • codex app-server RSS: ~487 MB
  • Overall system CPU was ~90% idle, memory pressure reported 56% free, and swap usage was zero

Local Codex state:

  • ~/.codex/sessions: 7.3 GB / 829 files
  • ~/.codex/archived_sessions: 3.7 GB / 449 files
  • ~/.codex/logs_2.sqlite: 1.7 GB
  • Largest individual rollout files: ~1.72 GB, ~1.68 GB, and ~608 MB
  • Log DB aggregates: 267,433 TRACE rows (~257 MB estimated payload)
  • Largest log targets by estimated payload:
  • codex_mcp::connection_manager: ~102 MB
  • codex_api::sse::responses: ~82 MB
  • codex_core::stream_events_utils: ~51 MB

Important caveat: during a five-second idle sample, the SQLite DB/WAL did not grow and renderer CPU later settled around 1–2%. So I cannot confirm continuous write churn or a permanent CPU spin. The strongest local signal is accumulated hot thread/rendering state plus V8 GC pressure, with the large log DB potentially amplifying it.

The app had updated to this build earlier the same day, but I do not yet have an older-build control test. No local data was deleted or modified during diagnosis.

devansh-jain-18 · 4 days ago

Follow-up after a full Codex Desktop restart: the UI remained very slow, so restart is not an effective workaround in this environment.

Fresh-process evidence roughly eight minutes after relaunch:

  • Renderer RSS grew from ~580 MB to ~692 MB over the observation window.
  • Renderer CPU repeatedly spiked, reaching ~25.5%.
  • A new 3-second renderer sample again showed the main thread dominated by V8 execution and v8impl::Reference::InvokeFinalizerFromGC.
  • Renderer physical footprint was ~446 MB at sample time, with an ~889 MB peak since the fresh launch.
  • codex app-server briefly reached ~21% CPU and ~550 MB RSS, although a later sample mostly found its Tokio workers waiting rather than a continuously hot loop.
  • One minute of the fresh session generated 1,097 SQLite log rows / ~2.81 MB estimated payload. About 2.37 MB came from rmcp::service; other leading sources were MCP connection management and app-server outgoing-message TRACE logs.
  • SQLite WAL size remained stable during a short six-second sample, so this still does not prove continuous disk-write churn.

The desktop startup log also emitted repeated:

  • ResizeObserver loop completed with undelivered notifications
  • IAB_LIFECYCLE route window is not live
  • IAB_LIFECYCLE browser use route window missing for cursor/active state

Those Browser Use warnings referenced many existing and client-new-thread conversation IDs during startup reconciliation. They appear related to the IAB route-management issue family (for example #20678), but I cannot prove they are the primary cause of the UI lag. My current read is that they may amplify the long-thread/state-replay problem described here.

System pressure remained low: zero swap and generally high CPU idle. This makes a persistent Desktop build/state-reconciliation issue more likely than machine-wide resource pressure.

sukhanov9425-dev · 4 days ago

Adding a fresh Windows Desktop reproduction from the current app build. This appears to match this issue and the symptoms reported in #19923 and #20544.

Environment

  • OpenAI Codex Desktop: 26.707.12708.0
  • Windows 11 Home Single Language, version 10.0.26200 (build 26200)
  • 32 GB RAM
  • AMD Ryzen 9 5900HX, 16 logical processors
  • AMD Radeon Graphics driver 31.0.21925.1001 (2026-05-20)
  • NVIDIA GeForce RTX 3070 Laptop GPU driver 32.0.16.1074 (2026-02-07)

Reproduction and symptoms

  1. Start Codex Desktop and switch between local threads.
  2. Opening certain tool-heavy or image/screenshot-heavy threads makes mouse-pointer movement and typing in Codex stutter for several seconds.
  3. The UI then recovers without a formal application hang.
  4. Some affected threads have only one to three visible user turns, so visible conversation length is not a useful predictor; the hidden tool/output history appears to matter much more.

Privacy-safe local measurements

During a 35-second sample while opening an affected thread:

  • The main ChatGPT.exe process working set grew from about 356 MB to 1,784 MB.
  • Its peak CPU was 9.77% of total system CPU across 16 logical processors.
  • Other renderer/GPU/utility child processes were mostly idle during the spike.
  • The main process later returned to about 364 MB working set after the UI recovered.
  • Across all Codex/ChatGPT processes, combined working set rose from about 1.36 GB to 2.46 GB, with private memory peaking around 2.84 GB.

Examples of short but internally heavy local histories:

  • A Blender/computer-use thread with one completed visible turn: 5.72 MB rollout, 289 JSONL records, 78 tool-output-related lines, and 14 image/screenshot-related lines.
  • Another short Blender thread: 4.83 MB rollout, 282 JSONL records.
  • No raw thread contents, paths, IDs, images, or unsanitized logs are included here.

Troubleshooting already performed

  • Clean reboot.
  • Updated the AMD display driver and verified both active display-driver versions.
  • Forced the Codex executable to the high-performance GPU preference.
  • Closed the separate ChatGPT Classic app.
  • Cleared/moved seven temporary caches (HTTP, GPU, shader, Dawn, and Sentry queue) and restarted Codex.
  • Checked Windows Application Error/Hang events; no new formal hang event was recorded during this reproduction.
  • System RAM was not exhausted.

The behavior remained unchanged after all of the above. The transient growth and later release of the main-process working set make this look like expensive thread-state materialization/deserialization or GC on the UI-critical path rather than a GPU-driver or machine-capacity problem.

Expected behavior: old tool outputs and image/screenshot records should be lazily hydrated or virtualized so that switching threads does not block pointer and keyboard input.

I can provide sanitized per-process samples or collect a specific performance trace if maintainers indicate which artifact would be most useful.