[Windows][26.727.6591.0] Avoid creating unused avatar-overlay renderer and bound renderer lifecycle
Summary
On Windows Codex Desktop, an unused avatar-overlay renderer is created during startup even when the user does not use avatars or pets. The extra renderer is small by itself, but it is an unnecessary Electron/Chromium surface and appears alongside the broader renderer/GPU memory problem.
Environment
- Windows x64
- Microsoft Store package:
OpenAI.Codex 26.727.6591.0 - Codex app build:
26.727.51351 - Executable:
ChatGPT.exe - Chromium reported by the app:
150.0.7871.182
Measurements
On a clean launch after clearing local Codex session/thread data and disposable Chromium caches:
- Codex created 8–9
ChatGPT.exeprocesses. - Clean-launch private memory reached approximately 1.6 GB.
- Three renderer processes were present.
- The renderer with Electron
--renderer-client-id=10was the avatar-overlay surface and used approximately 21 MB private memory. - Terminating only that renderer left the main Codex window responsive, reduced the process count from 8 to 7, and produced a live snapshot of approximately 912 MB private memory / 943 MB working set.
- A local launcher that trims only that renderer kept browser, Chrome, and computer-use features enabled.
- Disabling browser/Chrome/computer-use plugins reduced one clean snapshot from approximately 1.63 GB to 1.25 GB, but three renderers still remained.
- Disabling GPU acceleration made memory worse, reaching approximately 1.94 GB, so GPU disablement is not a viable workaround for this build.
These results do not prove the avatar overlay is the primary leak. They show that it is an unnecessary renderer that can be safely removed for users who do not use that feature, and that renderer/GPU lifecycle remains relevant to the larger memory issue.
Proposed solution
- Do not create the avatar-overlay BrowserWindow/renderer unless the avatar feature is enabled and actively needed.
- Treat “no avatar/pet selected” as a hard gate before creating the overlay composition surface.
- When the feature is hidden, dismissed, or disabled, destroy the BrowserWindow and release its webContents, IPC listeners, timers, and compositor resources instead of keeping a hidden renderer alive.
- Add renderer/window-appearance telemetry so memory reports identify primary, browser, and avatar-overlay surfaces.
- Add a bounded renderer/GPU memory regression test for a clean Windows startup and for long-running sessions.
Temporary local workaround
Fully exit all ChatGPT.exe processes and relaunch without the unused avatar overlay. Do not delete project repositories. Clearing stale session/tab state may reduce startup pressure, but it does not fix the underlying renderer memory bug.
Related issues
- #36561 — Windows renderer repeatedly soft-restarts after rapid memory growth.
- #35963 — Windows desktop app exits unexpectedly after memory-leak and hang events.
- #32474 — Windows
/C:/...path normalization and app-server failure. - #26362 — Renderer replacement while the main app/app-server remains alive.
- #18589 — Renderer RAM runaway followed by apparent app refresh/restart.
- #20867 — Long-thread rendering degradation on Windows.
The avatar-overlay finding is a narrower, actionable renderer-lifecycle issue that may contribute to the broader memory and hang symptoms in the linked reports.
2 Comments
Additional current-build evidence, migrated from #37073 before closing that report as a duplicate of this issue.
Environment: Codex App
26.730.61309(build6223), MSIXOpenAI.Codex_26.730.7989.0_x64, Windows10.0.26200.0x64, NVIDIA RTX 5060.Findings from the packaged production JavaScript and live Desktop logs
avatarOverlayBrowserWindow is created with background throttling disabled, and the main process also callswebContents.setBackgroundThrottling(false). It mounts the common React application/bootstrap rather than a minimal pet-only surface.Reasoning summary item completedevent count was 453 for the visible primary renderer and 453 for the hidden avatar overlay. The hidden overlay was logged asrendererWindowVisible=falseand also processed unknown-conversation/placeholder-turn activity.ChunkedMessageSendermaintains per-targetcriticalMessagesandmessagesarrays. While a large transfer is waiting for renderer ACKs, subsequent messages are appended. I found no byte/count cap, stale-delta coalescing, or ACK timeout on those queues. This is a proven static risk, not a claim that the live queue length was directly measured: a slow hidden renderer can retain subsequent traffic in the Electron main process until it drains or is destroyed.ResizeObserver loop completed with undelivered notificationserrors, and the main process recorded fourmain_thread_jank_snapshotevents. In this build the jank sampler records after approximately 900 ms or more of scheduling delay.26.730bundle skips the periodic child-process snapshot. Tool-launched PowerShell and a one-time startup WMI call do not explain the duplicate renderer delivery above.These findings strengthen the proposed lifecycle fix here: do not create the overlay until needed; destroy or suspend it when hidden; route only compact pet-specific state to it; and bound/coalesce every per-window IPC queue with ACK timeout and slow-target eviction.
Suggested acceptance checks:
Related evidence: #20680 (overlay/compositor and Windows input-lag A/B), #32789 (events duplicated to primary and avatar overlay), #33996 (reasoning updates and ResizeObserver freezes), and #36561 (long-session renderer growth plus duplicate UI delivery).
Additional independent reproduction on a newer Windows build (captured 2026-08-15).
Environment
OpenAI.Codex 26.810.6296.010.0.26200--device-scale-factor=2.5electron-avatar-overlay-open=falseUser-visible symptom
During a long remote Codex turn that streamed reasoning summaries, the whole desktop became periodically unresponsive and a small side bubble containing
Ctrl+repeatedly appeared. The problem cleared after fully restarting Codex, then returned during a later long streamed turn.This was not remote compute load: the runaway was in the local Electron desktop process.
Measured impact
Before restart:
After a clean restart:
Correlated Desktop-log evidence
In a bounded affected window (10:19–10:35 UTC), after excluding conversation text and filesystem paths:
avatarOverlay: 313rendererWindowAppearance=avatarOverlay rendererWindowVisible=false: 703ResizeObserver loop completed with undelivered notifications: 40main_thread_jank_snapshot: 106unknown conversationerrors: 255The hidden surface was
rendererWebContentsId=2; the visible primary surface wasrendererWebContentsId=1.A targeted experiment terminated only the later-created avatar renderer (
--renderer-client-id=6). Electron immediately recreated it under a new PID, while the main process remained at 15.47% whole-machine CPU / 123.8% of one core. This suggests that killing the hidden renderer cannot recover the incident because the main-process overlay lifecycle automatically recreates it.The packaged app also contains an
avatarOverlayCpuOptimizationsfeature gate whose local fallback/default isfalse. I cannot confirm the active server-side value, so this is implementation context rather than proof of the active configuration.Reproduction pattern
avatarOverlaystill receives a 1:1 copy of the primary renderer's reasoning events.ResizeObservererrors and main-thread jank snapshots accumulate, and the Electron main process sustains roughly one hot core.This newer-build reproduction strengthens the lifecycle fix proposed in this issue:
Raw logs are intentionally not attached because they include conversation metadata. Sanitized bounded excerpts can be provided privately if maintainers request them.