[macOS App] Opening integration-heavy tasks spawns persistent renderers that survive archive and idle

Open 💬 1 comment Opened Jul 16, 2026 by adamcooper

Summary

Codex Desktop on macOS accumulates child Codex (Renderer) processes when opening tasks that contain many inline integration/tool-result cards. Reopening the same task creates additional renderer processes. Navigating away, archiving the task, and waiting several minutes do not terminate them.

The renderers may have their resident memory trimmed while idle, but the processes and almost all of their threads remain. Fully quitting and relaunching the app is the only cleanup observed.

Environment

  • Codex/ChatGPT desktop app: 26.707.72221 (build 5307)
  • Bundled Codex CLI: 0.144.2
  • macOS: 26.5.1 (build 25F80)
  • Architecture: Apple Silicon / arm64
  • Hardware: M4 MacBook Air, 24 GB RAM
  • Displays during the initial tests: built-in display plus two 6016×3384 displays
  • Later archive/idle tests: battery power with only the built-in display online

The renderer-lifecycle behavior reproduced across both display configurations.

Reproduction

  1. Fully quit and relaunch Codex Desktop.
  2. Open a task containing many inline integration results (for example, Slack, GitHub, Jira, or Confluence result cards).
  3. Switch to another task and reopen the integration-heavy task several times without expanding or interacting with individual cards.
  4. Observe direct child Codex (Renderer) processes after each opening.
  5. Navigate away from the task.
  6. Archive it from the sidebar without reopening it.
  7. Wait several minutes and inspect the process tree again.

Controlled results

Fresh restart

| Metric | Before restart, accumulated session | After restart, first task only |
| --- | ---: | ---: |
| Live renderers | 388 | 2 |
| Renderer RSS | 27,371 MiB | 507 MiB |
| Renderer threads | 7,498 | 33 |
| Total Codex-related processes | 412 | 17 |
| Total Codex-related RSS | 28,662 MiB | 1,808 MiB |

Five repeated openings of one integration-heavy task

Before this test, 21 renderer processes were alive.

| Metric | Before | After five openings | Change |
| --- | ---: | ---: | ---: |
| Live renderers | 21 | 26 | +5 net |
| New renderer starts | — | 6 | +6 |
| Renderer RSS | 3,049 MiB | 3,709 MiB | +660 MiB |
| Renderer threads | 375 | 466 | +91 |
| Browser navigation events | 0 | 0 | 0 |

The app log recorded exactly five activations of the affected task. Renderer process start times aligned with those activations:

| Task activation | Renderer starts |
| --- | --- |
| 17:54:14 | 1 |
| 17:54:25 | 1 |
| 17:54:28 | 1 |
| 17:54:32 | 1 |
| 17:54:35 | 2 |

One older renderer exited during the interval, giving a net increase of five. The task had no Browser sidebar activity, so these were not Browser guest renderers.

After approximately ten idle minutes, all 26 renderers remained alive. Renderer RSS fell from 3,709 MiB to 2,234 MiB, consistent with inactive working-set trimming, but no renderer process was cleaned up.

Separate Confluence-heavy task and archive test

Opening another task that rendered many inline Confluence/integration snippets produced:

| Metric | Before task | Before archive | Change |
| --- | ---: | ---: | ---: |
| Live renderers | 26 | 35 | +9 net |
| New renderer starts | — | 10 | +10 |
| Renderer RSS | 2,234 MiB | 3,219 MiB | +985 MiB |
| Renderer threads | 489 | 663 | +174 |

Merely navigating away left all 35 renderers alive.

Archiving the task succeeded. Desktop logs recorded:

  • thread/archive completed
  • browser-use route disposed
  • browser-use conversation disposed
  • worktree archive cleanup completed
  • no Browser guest teardown
  • no renderer exit

| Metric | Before archive | Immediate post-archive | Approximately 3.5 minutes later |
| --- | ---: | ---: | ---: |
| Live renderers | 35 | 35 | 35 |
| Renderer RSS | 3,219 MiB | 3,409 MiB | 3,126 MiB |
| Renderer threads | 663 | 660 | 659 |
| Guest teardowns | 0 | 0 | 0 |

Expected behavior

Opening a task or hydrating inline integration history should reuse a bounded renderer set. Renderers associated with task-local tool views should be terminated or otherwise released when their views are unmounted, their route is disposed, or the task is archived.

Actual behavior

Each opening of an integration-heavy task creates additional renderer processes. Those processes survive navigation, task archive, and idle time. Memory may be compressed or reclaimed, but the process and thread counts remain accumulated for the lifetime of the desktop app.

Workaround

Fully quit and relaunch Codex Desktop. This immediately reduced the observed renderer count from 388 to 2. The accumulation begins again as integration-heavy tasks are opened.

Feedback and diagnostics

An in-app feedback upload with logs completed successfully at 2026-07-16T01:30:56Z. The UI feedback ID was not retained. The local app-server request correlation was 22402790-801d-4045-8e05-fe5a6cd67302.

Timestamped process reports and additional sanitized excerpts are available. Raw app logs are not attached publicly because they contain private task text and local paths.

Related issues

  • #18589 — high content-renderer RAM usage on macOS
  • #33285 — unbounded transcript hydration/rendering when opening long tasks
  • #30464 — renderer/WindowServer load on an M4 MacBook Air
  • #31793 — adjacent Chromium/Electron memory accumulation in the macOS main process

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗