Desktop performance collapses in profiles with a few very large local conversation histories (typing, scrolling, thread list, random exits)

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

Summary:<br>This is broader than slow thread switching. In profiles that contain a small number of extremely large local conversation histories, Codex desktop becomes slow across multiple surfaces: typing, scrolling inside a conversation, scrolling the thread list, delayed UI updates, slow thread switching, and occasional app exits. My strongest verified signal is not total conversation count, but the presence of a few giant local histories. Some of those heavy histories also had recurring thread heartbeat automations attached, which may amplify the problem, but that variable is not yet fully isolated.

Environment:

  • Codex desktop app 26.415.40636
  • macOS 26.3
  • MacBook Pro (Apple M3 Max, 16 CPU cores, 128 GB memory)

Observed

  • Typing can become very slow, roughly ~1s for words to appear.
  • Scrolling inside an existing conversation can become very slow.
  • Scrolling the thread list can become very slow.
  • UI updates such as archive notifications can arrive with noticeable delay.
  • Switching into some older conversations can take a very long time.
  • The app can also exit unexpectedly.
  • This appears Codex-specific on my machine: the slowdown can show up immediately inside Codex while the rest of the machine feels normal.

Verified A/B Repro

I tested this by comparing copied local profiles rather than only changing one profile in place.

Verified results:

  • A fresh test profile was smooth.
  • A copied profile that kept most of my original conversations but excluded the largest bloated ones was also smooth.
  • A copied profile that restored only a few very large historical conversations became slow again, even without the rest of my normal active conversations.

What this establishes:

  • The strongest correlation I can verify so far is the presence of a few giant local histories, not raw total conversation count by itself.
  • This is broader than thread-switch latency. The same profiles also show typing lag, scrolling lag, delayed UI updates, and occasional app exits.

What I have not isolated yet:

  • Whether simply archiving those same conversations inside the main profile would be enough to fix it.
  • Whether recurring thread heartbeat automations targeting those same heavy conversations are contributing independently, or mainly amplifying an existing history-size problem.

Hypotheses

These are hypotheses, not claims of proof:

  • The desktop app may be over-hydrating, resuming, or indexing a few massive local conversation histories.
  • Stale stored workspace roots may be adding background churn during startup and/or resume.
  • Recurring thread heartbeat automations attached to already-large conversations may amplify the problem by repeatedly waking expensive local histories.

My current read is that the issue is likely caused by some combination of:

  1. oversized local history payloads
  2. resume/read/index churn on those histories
  3. stale workspace-root scanning
  4. possibly heartbeat-driven repeated wakeups on the same heavy conversations

Diagnostics

Largest local histories on this machine, anonymized:

<!-- linear:table-colwidths:200,200,200,200 -->
| Local history | Rollout size | Turn contexts | Function/tool calls |
| -- | -- | -- | -- |
| [#1](<https://github.com/openai/codex/issues/1>) | 1867.27 MiB | 618 | 21,369 |
| [#2](<https://github.com/openai/codex/issues/2>) | 584.72 MiB | 5,554 | 22,434 |
| [#3](<https://github.com/openai/codex/issues/3>) | 561.02 MiB | 554 | 22,831 |
| [#4](<https://github.com/openai/codex/issues/4>) | 507.22 MiB | 428 | 17,991 |
| [#5](<https://github.com/openai/codex/issues/5>) | 455.84 MiB | 563 | 38,073 |

Additional local signals:

  • local state currently has 1767 total conversations, 777 unarchived
  • 40 stored workspace roots no longer exist
  • the desktop backend had 8 old session histories open totaling about 1.66 GiB
  • desktop logs showed thread resume/read/unsubscribe operations taking tens of seconds, with worst cases around 82s
  • startup also repeatedly scanned stale worktree/origin roots with very large expanded counts

Related issues

This may overlap with:

View original on GitHub ↗

19 Comments

github-actions[bot] contributor · 3 months ago

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

  • #18568
  • #18333
  • #18264

Powered by Codex Action

venkatd · 2 months ago

I believe I am having the same issue. I have about 2-3 long running sessions (1 week long sessions). Switching sessions is slow, focusing on the chat box is slow. Things will lock up in all cases.

It's preventing me from enjoying it as much as I used to. Number one feature request is to speed it up. Thanks!

Shot in the dark, but does Codex do any virtualization in the chats? If not, perhaps using something like https://github.com/chenglou/pretext would unlock efficient virtualization by allowing calculating text heights efficiently.

venkatd · 2 months ago

If it helps, I can confirm that archiving the conversations fixes the performance. Once I archived the long sessions and started new ones, things got much faster again.

One of my conversations was a bit over 1GB.

wousp112 · 2 months ago

I’m also seeing this multi-thread / large-history slowdown on Codex Desktop for macOS.

Setup:

  • Mac with 16GB RAM
  • Codex Desktop version: 26.417.41555 (build 1858)
  • macOS version: macOS 26.4.1 (25E253)

Local state:

  • ~/.codex/sessions is around 5.2GB
  • Largest rollout file is around 207MB
  • Several rollout files are over 80-130MB

Behavior:

  • Disabling Memory made the app much smoother for single-window usage.
  • However, opening multiple threads/windows still causes noticeable lag.
  • Renderer processes continue to consume significant CPU/RAM when several threads are open.
  • Thread switching and general UI responsiveness degrade as more large histories are present.

This seems related to large local history hydration/thread switching, possibly made worse when Memory is enabled.

twentyOne2x · 2 months ago

Can I work on these Linear tickets myself @yevin-oai? 😁
Still experiencing the same issues, the most annoying of which being codex dying quickly
Lots of loooove to you and the team
CLI-6413
CLI-6450

guidedways contributor · 2 months ago

Coincidentally have the exact same setup / hardware and with version Version 26.422.30944 (2080) running into extreme slowness due to an ongoing session that's now lasted 24 hours (and still another 12 hours or more to finish). I cannot archive the session as it's been working for more than 24 hours on a major refactor.

I'd love for past messages in the same session to auto-hide / collapse into a single Load more section of some kind. Due to this, dictation has stopped working too it seems - taking ~30 seconds to transcribe a short 5 second audio which otherwise is instant.

dezmen3 · 2 months ago

Weird that app does not have hide option or reveal old chat messages only when you scroll. A 3 days of chat is gigantic and freezes app while we don't even need to see most of old content visually in UI, codex can look at it somewhere internally, but app is chocking

venkatd · 2 months ago

Can anyone confirm where the performance bottleneck is? If it's rendering, I think the codex team could add virtualized rendering to make things feel instant. Using a lib like pretext could allow pre-computing message heights in advance.

yaananth · 2 months ago

I got a repro locally and I pointed that to codex, here is what it says :)

I can confirm at least one major bottleneck is renderer-side. In a live stuck Codex Desktop instance, the Electron renderer was sitting around ~100% CPU with ~1.5-2.6GB RSS, while the app-server process stayed low CPU. A macOS sample of the renderer showed the main thread in V8/JS/JIT frames and memory-copy work, which points more to renderer state/render/layout churn than backend compute. That said, I don’t think virtualization alone is the whole fix if the app still eagerly hydrates giant histories into renderer state. The desktop flow appears intended to be lazy: read metadata, load a small recent tail via thread/turns/list, then resume with excludeTurns: true. But there is also a loadRemainingConversationTurns path that can continue paging older turns after resume. If that runs automatically, it defeats the lazy design and eventually puts the giant history back into the renderer. So my current read is: 1. Yes, rendering/renderer work is a real bottleneck. 2. Virtualized transcript rendering would likely help a lot. 3. But the durable fix should also prevent background full-history hydration. 4. Older turns should load only on scroll/load-more, and only visible urns should be mounted/rendered. 5. Sidebar/global conversation state should stay metadata-only and not carry large turn arrays. I also found one backend amplification bug: for already-running threads, thread/resume was still loading full persisted history even when the client sent excludeTurns: true. That should be fixed too, but I’d treat it as enforcing the lazy contract, not as the complete renderer-performance fix.
twentyOne2x · 2 months ago

I think its solved btw. No longer experiencing this despite the same threads and usage pattern e.g. thread automations for several threads and projects.

rhdtl78 · 2 months ago

I can reproduce what looks like the same large-history / long-session performance failure on a newer Codex Desktop build, with a more specific trigger: after restarting Codex, loading a very long existing session appears to put the desktop app into sustained high CPU.

Environment

  • Codex Desktop: 26.429.30905 (CFBundleVersion 2345)
  • macOS: 26.4.1 (25E253)
  • Darwin: 25.4.0
  • Architecture: arm64
  • Timestamp: 2026-05-04 18:29-18:30 KST

Trigger observed

  1. Restart Codex Desktop.
  2. Open/load a long existing session with a very large conversation/tool history.
  3. The app becomes hot and CPU stays high.
  4. Cleaning stale/duplicate MCP processes does not resolve the high CPU, and MCP/LSP sidecars remain idle.

This makes it look more tied to long-session hydration/render/resume after restart than to MCP process CPU.

CPU samples

Collected with:

ps -axo pid,ppid,%cpu,%mem,etime,command \
  | rg 'Codex|codex|serena|rust-analyzer|sourcekit-lsp|TypeScriptLanguageServer|tsserver|mcp|SkyComputerUseClient|playwright|context7|redmine|grafana|Pencil' \
  | rg -v rg \
  | sort -k3 -nr

Sample 1

Codex main process:              247.6% CPU, 5.2% MEM
Codex Helper Renderer:           105.1% CPU, 2.9% MEM
codex app-server:                 17.5% CPU, 0.6% MEM
Codex GPU process:                14.7% CPU, 0.4% MEM
MCP/LSP sidecars:                  0.0% CPU

Sample 2

Codex main process:              239.5% CPU, 4.8% MEM
Codex Helper Renderer:           105.0% CPU, 2.9% MEM
Codex GPU process:                13.6% CPU, 0.4% MEM
codex app-server:                  1.4% CPU, 0.6% MEM
MCP/LSP sidecars:                  0.0% CPU

Sample 3

Codex main process:              240.1% CPU, 4.8% MEM
Codex Helper Renderer:           102.5% CPU, 2.9% MEM
Codex GPU process:                16.3% CPU, 0.4% MEM
codex app-server:                  0.0% CPU, 0.6% MEM
MCP/LSP sidecars:                  0.0% CPU

MCP/LSP state

Before collecting the samples, stale duplicate MCP generations were cleaned up. Remaining sidecars were idle:

serena start-mcp-server:          0.0% CPU
rust-analyzer:                    0.0% CPU
sourcekit-lsp:                    0.0% CPU
typescript-language-server:       0.0% CPU
playwright/context7/redmine MCP:  0.0% CPU
mcp-grafana:                      0.0% CPU

Notes

This may also overlap with #20435, but the stronger repro signal here is: restart Codex, then load a very long existing session. The high CPU sits in the Codex main process plus renderer while MCP/LSP sidecars are idle.

Expected behavior: loading a large historical session may take some time, but should not leave the main process around ~240% CPU and renderer around ~100% CPU after the session is already visible.

vorojar · 2 months ago

Adding another Windows reproduction signal from Codex Desktop 26.429.3425.0.

Environment:

  • Codex desktop package: OpenAI.Codex_26.429.3425.0_x64__2p2nqsd0c76g0
  • Platform: Windows, PowerShell environment, local profile under %USERPROFILE%\.codex
  • User-visible symptom: clicking/opening a conversation with a very large history makes Codex Desktop freeze. CPU keeps rising while the UI remains unresponsive. This is not only an auto-resume-at-launch case; the oversized thread can be selected manually from the thread list and cause the freeze.

Local size signals:

| Size | Lines | Path |
|---:|---:|---|
| 315.40 MB | 10,917 | %USERPROFILE%\.codex\sessions\2026\04\28\rollout-2026-04-28T07-40-53-019dd151-3571-7230-ab00-407fad5e5857.jsonl |
| 67.69 MB | 2,059 | %USERPROFILE%\.codex\sessions\2026\04\30\rollout-2026-04-30T20-18-06-019dde53-2d23-7063-b325-6b8c61a7e86c.jsonl |
| 12.07 MB | 1,072 | next largest rollout |

Additional local state:

  • %USERPROFILE%\.codex\logs_2.sqlite is about 301 MB.
  • During inspection, the largest Codex renderer process had about 831.8 MB working set and high accumulated CPU (~825 CPU seconds) while the app had been running since May 3.

Repro pattern:

  1. Use Codex Desktop on Windows long enough to accumulate one or more large local rollout JSONL histories.
  2. Open the thread list.
  3. Click the largest / very content-heavy conversation.
  4. Codex Desktop becomes unresponsive and CPU keeps increasing.
  5. Restarting Explorer does not matter; the problem is inside Codex Desktop / local session hydration.

Expected behavior:

  • Opening a large thread should not block the renderer/main UI.
  • The app should either lazy-load/paginate the history, render only recent turns first, or guard large rollouts with a prompt such as "this thread is large; open truncated view / continue anyway".
  • Large local histories should be archiveable or removable from the UI without needing manual filesystem intervention.

Privacy note: I am intentionally not uploading raw .jsonl, sqlite databases, auth files, screenshots, or unsanitized logs. The paths above are sanitized to %USERPROFILE% and included only to identify the local storage class involved.

vorojar · 2 months ago

I also prepared a forward-looking containment patch branch here:

https://github.com/vorojar/codex/tree/codex/bound-rollout-output-size

Commit: vorojar/codex@d63bd59

What it changes:

  • bounds persisted ResponseItem::FunctionCallOutput / CustomToolCallOutput text at the rollout recorder boundary
  • truncates structured InputText content items while preserving non-text content items
  • keeps the existing extended-mode ExecCommandEnd.aggregated_output truncation behavior intact

Validation:

  • added failing regression tests first for unbounded persisted function/custom tool output
  • cargo fmt --all --check
  • cargo test -p codex-rollout --no-default-features

I attempted to open this as a draft PR from the fork, but GitHub rejected PR creation from my account/token for this repository (CreatePullRequest / Resource not accessible by integration). The branch is pushed and available if maintainers want to import/cherry-pick it.

This does not migrate existing giant session files; it only prevents future sessions from being inflated by very large persisted tool output. A true fix for already-large histories still needs indexed/lazy loading in the desktop/app-server path.

pcui-coder2 · 2 months ago

Adding another confirmed case that looks like the same class of bug, with one useful isolation detail.

Environment:

  • Codex Desktop 26.429.61741
  • Bundled CLI reports codex-cli 0.128.0-alpha.1
  • macOS desktop app

Observed:

  • Codex Desktop became noticeably laggy after upgrading to the latest version.
  • Reinstalling Codex did not help, because the relevant state persisted under ~/.codex.
  • Lag was worst when switching projects in the left sidebar.
  • Desktop logs showed thread/list calls taking about 2.2s-4.8s before cleanup.
  • The profile had about 1.6G under ~/.codex/sessions.
  • About 1.5G of that was tied to one generated workspace, roughly <workspace>/aidev/runtime/codex-workspace.
  • The state DB still had many unarchived rows for that old workspace even after the project was removed from the sidebar.

Important isolation result:

  • I first suspected plugins/MCPs because logs also showed slow app/list, plugin/list, and mcpServerStatus/list.
  • After a deeper cleanup, the UI returned to normal.
  • I then re-enabled all plugins/MCPs and the UI stayed fast.
  • So in this case the primary root cause was stale active session/thread history, not plugins.

What fixed it:

  • Quit Codex completely.
  • Back up ~/.codex/state_5.sqlite, ~/.codex/.codex-global-state.json, and ~/.codex/session_index.jsonl.
  • Archive stale rows in state_5.sqlite.
  • Move old rollout JSONL files out of ~/.codex/sessions so the app cannot rebuild active rows for deleted/old projects.
  • Reset Electron app support/cache.

After cleanup:

  • Active threads dropped to 5.
  • Archived threads were 176.
  • Plugins/MCPs were re-enabled.
  • Sidebar project switching stayed fast.

Expected behavior:

  • Removing a project from the sidebar should not leave a large set of stale active threads that continue to affect sidebar/project switching performance.
  • Codex Desktop should not repeatedly rebuild or scan old local session files in a way that makes project switching lag.
  • Large local conversation/session histories should be virtualized, lazily indexed, or safely excluded once archived/deleted.
rdylina · 2 months ago

Another strong repro: the problem correlates with a few giant histories, not high thread count. One 825MB completed rollout caused ~4.5-5GB app-server RSS after opening, 148-253s app-server responses, and a dropped 405MB stream-state payload. The hot path appears to be large histories being hydrated/resumed, not just general UI/system load.

rdylina · 2 months ago

Follow-up / PR offer: I read the contribution docs and understand external PRs are invitation-only. If the team thinks this direction fits, I’d be happy to take a stab at an invited PR for the open-source app-server side.

Conceptually, the fix I’d propose is:

  • in no case should opening a thread load the entire transcript into app-server + client state
  • open threads from metadata + the latest tail only, roughly the most recent 100-200 messages or a small byte cap, whichever comes first
  • lazy-load older chunks only when the user scrolls upward / explicitly asks for them
  • compact or summarize the old head for model context instead of treating the full durable transcript as active state
  • keep large tool outputs/artifacts behind references, not inline in normal thread state
  • add hard byte/count limits so thread/read, thread/resume, and stream-state snapshots cannot produce 100MB+ payloads
  • document that Desktop/IDE clients should use paged turns/items and never full-hydrate a completed thread just because it was clicked

The desktop side still needs closed-code changes, but the app-server can provide the safe bounded contract and fail gracefully when a client asks for full hydration of an oversized rollout.

rijhsinghani · 2 months ago

Adding a current datapoint from another affected macOS workstation. This still reproduces on a newer CLI build and looks consistent with the large-local-history/random-exit family described here.

Environment:

  • Codex CLI: codex-cli 0.130.0
  • Install path: /opt/homebrew/bin/codex
  • macOS: 26.4.1 (25E253), Darwin 25.4.0, Apple Silicon / arm64
  • Machine: Mac Studio (Mac13,1 in crash report)
  • Shell/terminal: zsh in Terminal (TERM=xterm-256color)

Observed:

  • Codex CLI sessions randomly exit during normal long-running agent work.
  • macOS DiagnosticReports contains multiple recent codex-*.ips crash reports.
  • Representative crash report: codex-2026-05-08-195441.000.ips
  • procName: codex
  • procPath: /opt/homebrew/*/codex
  • exception: EXC_CRASH, SIGABRT
  • termination: Abort trap: 6, by process codex
  • process launched at 2026-05-08 19:11:29 -0400, exited/crashed at 2026-05-08 19:54:40 -0400
  • threads include tokio-runtime-worker and several sqlx-sqlite-worker-* workers

Local profile/history signals:

  • ~/.codex/archived_sessions: 1.4G
  • ~/.codex/logs_2.sqlite: 63M
  • ~/.codex/state_5.sqlite: 58M
  • Largest local rollout files currently present:
  • active session rollout: 681M
  • archived rollout: 363M
  • archived rollout: 193M
  • several additional rollout files between 46M and 77M

This looks like either the same root cause or a closely related CLI-side failure mode: large local histories plus long-running agent sessions eventually lead to abrupt process exit rather than graceful compaction, truncation, or recovery. I have not attached raw .ips or rollout files publicly because they may contain private repo/session data, but the crash report summary above is available from local diagnostics.

venkatd · 2 months ago

If the root cause is too much data at once from codex, might I propose that the codex team takes peek at Turso in place of sqlite?

A few things that might be relevant:

AVICII379 · 4 days ago

Adding a Windows 11 datapoint that closely matches this issue.

Environment

  • Codex Desktop Microsoft Store package: 26.707.9981.0
  • Windows 11 x64, build 26200
  • 32 GB RAM

Observed

  • Clicking or switching threads can intermittently make the window show ChatGPT (Not Responding) while the rest of Windows remains responsive.
  • Typing, scrolling, and sidebar interaction become delayed.
  • This does not correlate with disk pressure or overall memory exhaustion.

Local history profile (anonymized)

  • Session rollout data: about 2.06 GB
  • Initially 128 unarchived threads and 7 archived threads
  • 22 rollout files over 10 MB
  • 5 rollout files over 100 MB: approximately 586.8, 267.7, 267.7, 218.4, and 108.4 MB
  • One 218 MB thread was still growing in the background while another thread was in the foreground.
  • Inspection showed two concurrent inProgress turns on that large thread.
  • During the slowdown, the Electron main process, renderer, and app-server used about 1.8 GB combined.

Reversible A/B test

I archived five inactive giant threads totaling about 1.32 GB, without deleting rollout files and without touching the active large thread.

Afterward:

  • Unarchived thread count dropped from 128 to 123
  • Initial interactive sampling showed 0 non-responsive samples and 0 new crash events
  • CPU averaged about 16% with a 34% peak
  • Thread-list requests completed in roughly 160–410 ms
  • The main window remained responsive

This is preliminary because the active 218 MB background thread is still running, but the result supports the same large-history hydration/indexing pattern described here.

A durable fix likely needs:

  1. metadata-only sidebar state
  2. bounded recent-tail loading
  3. lazy loading of older turns
  4. virtualized transcript rendering
  5. protection against overlapping in-progress turns on the same large thread

No raw rollout files, local paths, thread IDs, screenshots, or dumps are included for privacy.

This also appears related to #11011.