ChatGPT Chrome Extension Causes a Controlled Renderer to Grow by ~0.65 GiB/min Until It Reaches 10+ GiB
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Bug
- Clarity
- Needs clarification
- Activity status
- Quiet
- Tech stack
- javascript
- Domain
- devtools, performance
Research direction
Start by reproducing the browser-control sequence while observing the renderer with Activity Monitor, ps, and vmmap. Inspect the chrome.debugger.onEvent forwarding, sendCommand path, and getTabContext page-context pipeline described in the issue. Done means identifying the retaining path and ensuring event production, temporary CDP values, uploads, and session cleanup cannot sustain unbounded renderer growth.
Written by the indexing model from the issue text.
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.721.41059
What subscription do you have?
Plus
What platform is your computer?
No response
What issue are you seeing?
Summary
The official ChatGPT Chrome extension causes a controlled webpage renderer to consume memory at a sustained rate of approximately 0.65 GiB per minute during a Codex browser-control operation.
The affected renderer grew from 7.8 GiB to approximately 13.0 GiB in about eight minutes. It also consumed more than 80% CPU and forced approximately 12.4 GiB of memory into swap.
Terminating only the affected renderer immediately stopped the growth and reduced total Chrome child-process RSS from approximately 4–5 GiB to approximately 2.1 GiB. System-wide free memory recovered from approximately 32% to 56%.
This appears to be a renderer-side retention issue triggered by the extension's browser-control pipeline, rather than ordinary Chrome cache growth or a leak in the extension service worker alone.
Environment
- Date observed: July 29, 2026
- Operating system: macOS 26.5.2 (25F84)
- Architecture: Apple Silicon / ARM64
- Google Chrome: 150.0.7871.187
- ChatGPT Chrome extension ID:
hehggadaopoacecdllhhajmbjkdcmajg - ChatGPT Chrome extension version:
1.2.27221.15725 - Extension description:
Control Chrome with ChatGPT. - Extension background implementation: Manifest V3 service worker
- Chrome parent process PID during the reproduction:
37204 - Affected renderer PID:
77035 - Codex/ChatGPT desktop version: 26.721.41059
Impact
- Severe memory pressure and swap growth within minutes.
- Sustained high CPU usage.
- Potential system-wide UI stalls or hangs.
- Risk of out-of-memory termination or forced reboot.
- The problem can continue after a browser-control operation stalls or times out.
- Recovery currently requires terminating the affected renderer or restarting the extension/browser-control session.
What steps can reproduce the bug?
Steps to Reproduce
The precise prompt and target webpage can be added if needed, but the observed sequence was:
- Install and enable the official ChatGPT Chrome extension.
- Connect Codex/ChatGPT to the existing Chrome profile through the extension.
- Start a browser-control task that operates on an existing webpage.
- Allow Codex to inspect or manipulate the page using DOM, JavaScript evaluation, screenshot, page-context, or related browser-control operations.
- Observe Chrome processes in Activity Monitor or with
psandvmmap. - A newly created
Google Chrome Helper (Renderer)process begins using high CPU and grows by hundreds of MiB per minute. - The growth continues after the browser operation stalls or times out.
What is the expected behavior?
Expected Behavior
- Browser-control operations should use bounded memory.
- CDP commands and page-context operations should release temporary values when they complete, fail, time out, or are canceled.
- The extension should stop high-volume event producers and detach its debugger session when a turn or browser-control session ends.
- A failed DOM/evaluation operation should not leave the controlled renderer allocating memory indefinitely.
Actual Behavior
The controlled renderer continued allocating memory while using high CPU.
Additional information
Follow-up measurement
At approximately 2026-07-29 04:22 UTC+00:00:
Physical footprint: 12.9G–13.0G
Physical footprint (peak): 13.1G
Writable regions: 13.7G total, 12.9G written
Swapped out: approximately 12.4G
CPU: approximately 80% or higher
This is an increase of approximately 5.2 GiB in eight minutes, or about 0.65 GiB/min.
Memory Breakdown
vmmap -summary 77035 reported:
Memory Tag 253: approximately 5.8G swapped
Memory Tag 255: approximately 6.6G swapped
Chromium defines these tags as:
kPartitionAlloc = 253;
kChromium = 254;
kV8 = 255;
This indicates that the growth consisted primarily of:
- V8 heap pages;
- Chromium
PartitionAllocallocations; - likely JavaScript objects, strings,
ArrayBufferbacking stores, serialized CDP results, page-context data, or related temporary values that remained strongly referenced.
This memory profile does not look like ordinary disk cache or a purely GPU/image-cache problem.
Process Identification
The runaway process command line included:
--type=renderer
--renderer-client-id=4063
It did not include:
--extension-process
Therefore, the 13 GiB allocation was not located in the extension service worker itself. It was located in a normal webpage renderer being controlled by the extension.
The Chrome parent process remained much smaller, with an observed physical footprint of approximately 0.8–1.1 GiB. Activity Monitor may visually associate the renderer's usage with the parent Chrome application, but the actual runaway allocation was owned by renderer PID 77035.
CPU Sample Observations
The attached macOS sample report shows:
- sustained work on the renderer main thread;
- repeated execution through addresses outside static binary images, consistent with V8 JIT-generated code;
- continued renderer activity rather than an idle process waiting to be reclaimed;
- no evidence that the majority of the footprint was an
IOSurfaceor GPU allocation.
The sample report is useful for proving the process identity, CPU activity, launch time, and 7.8 GiB footprint. Because the Chrome framework is stripped, it does not identify the exact JavaScript function responsible for the allocation.
Extension Code Paths That May Be Relevant
The following findings are based on a read-only inspection of extension version 1.2.27221.15725. They are hypotheses for investigation, not a claim that one specific path has already been proven as the sole root cause.
1. Unbounded CDP event forwarding
The extension registers a global chrome.debugger.onEvent listener and forwards every event to the native host without an apparent method filter, byte limit, bounded queue, sampling policy, or transport backpressure.
The effective data path is:
chrome.debugger.onEvent
-> onCDPEvent JSON-RPC notification
-> chrome.runtime.Port.postMessage
-> native messaging transport
-> com.openai.codexextension
The dynamic CDP command path ultimately calls:
chrome.debugger.sendCommand(target, request.method, request.commandParams)
This means the native host can dynamically enable high-volume domains or methods such as:
Page.startScreencast;Page.captureScreenshot;Runtime.evaluate;DOMSnapshot.captureSnapshot;Network.enable;Network.getResponseBody;- WebSocket frame events.
If event production is faster than the native host or app server can consume it, multiple layers may retain serialized event payloads.
2. Runtime or DOM objects may survive timeout/cancellation
The renderer-side V8 allocation suggests that CDP or injected-page values may remain alive after a failed operation.
Please verify that all completion, timeout, cancellation, disconnect, and turn-finalization paths perform the equivalent of:
Page.stopScreencast
Network.disable
Runtime.releaseObject / Runtime.releaseObjectGroup
Target.setAutoAttach(autoAttach=false)
chrome.debugger.detach
In particular, Runtime.evaluate calls should use a bounded lifetime for remote objects and release their objectGroup in a finally block.
3. Large getTabContext values and base64 duplication
The extension's page-context code can read content from the controlled tab and transform it through a pipeline resembling:
ReadableStream chunks
-> Uint8Array[]
-> Blob
-> data URL
-> full base64 string
-> structured clone
-> native messaging chunks
The binary path allows up to 100 MiB of raw content, which becomes approximately 133 MiB after base64 encoding before accounting for duplicate representations and structured-clone/IPC copies.
The text path does not appear to have the same 100 MiB total-size limit.
The full dataBase64 value can remain captured by an asynchronous upload closure until all native-host chunks finish. Some native-host asset requests do not appear to have a default timeout. Multiple concurrent requests could therefore retain multiple complete payloads.
4. High-volume screenshot or screencast traffic
A screencast frame is a base64-encoded compressed image. For example:
500 KiB/frame * 4/3 base64 expansion * 30 fps * 60 seconds
~= 1.17 GiB/min of payload
This makes screencast/event backpressure worth investigating. However, the large V8 portion in the affected webpage renderer means a pure image-buffer leak does not fully explain this reproduction. Screencast or screenshot traffic may be a trigger or amplifier rather than the only retained object type.
Cleanup Result
After collecting the process sample and vmmap evidence, renderer PID 77035 was terminated with SIGTERM.
Observed result:
Affected renderer: exited
Chrome child-process RSS before: approximately 4–5 GiB
Chrome child-process RSS after: approximately 2.1 GiB
System-wide free memory before: approximately 32%
System-wide free memory after: approximately 56%
Chrome itself remained running. The associated controlled tab was expected to crash or reload.
This confirms that the majority of the active memory pressure belonged to the single runaway renderer.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
A-linter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
oxc-project/oxc#26863 ·