Skip to main content
Guide SuperchargePerformance

How Chrome Manages Memory in 2026: Architecture and Leaks

Chrome runs one renderer per site. Site Isolation adds 10-13% RAM overhead but blocks Spectre. V8 heap, tab discard, and leak types explained for 2026.

11 min read Verified Chrome 149

Chrome with 20 tabs open runs roughly 35–60 OS processes simultaneously. Each tab is its own renderer process under Site Isolation. A browser process, GPU process, and Network Service process handle shared work. V8’s Orinoco garbage collector manages per-renderer heap allocation. Understanding this architecture explains every high-RAM symptom you will encounter.

Chrome’s Multi-Process Architecture

Chrome abandoned the single-process browser model in 2008. The original motivation was crash isolation: one bad tab should not bring down the entire browser. By 2018, security pressures from Spectre forced the architecture further toward full process isolation per origin.

Today’s Chrome session spawns these process types:

ProcessFunctionTypical RAM
Browser processUI, tabs bar, settings, extension management150–300 MB
Renderer process (per site)HTML parsing, JavaScript execution, layout80–300 MB each
GPU processCompositing, hardware-accelerated rendering, WebGL100–500 MB
Network ServiceDNS, HTTP/2, socket pools, cache50–100 MB
Utility (Audio Service etc.)Isolated service workers and audio20–50 MB each
Extension processesBackground scripts, service workers per extension30–150 MB each
Subframe processesEmbedded cross-origin iframes (often ad networks)20–80 MB each

The browser process is the coordinator. It holds the tab list, manages inter-process communication (IPC) via Chromium’s Mojo system, and survives renderer crashes. If a renderer dies, the browser process displays an “Aw, Snap!” error in that tab and spawns a fresh renderer — the session continues.

Why So Many Subframe Processes

A single news article with three ad networks can generate 8–12 Subframe processes. Each cross-origin <iframe> (different domain or subdomain than the parent page) requires its own renderer under Site Isolation rules. This is security-correct: a malicious ad frame in ads.example.com cannot read memory from yourbank.com if they run in separate processes.

In Chrome Task Manager (Shift + Esc), these appear as rows labeled “Subframe” with a URL. You can end any Subframe process individually without closing the parent tab. For persistent ad-iframe RAM drain, blocking at the network layer prevents the Subframe from being spawned at all.

Site Isolation: The Security-Memory Tradeoff

Site Isolation rolled out as the default for desktop Chrome in Chrome 67 (May 2018), about three months after Google’s disclosure of Spectre (January 2018). The rollout was urgent: Spectre-class attacks exploit CPU branch prediction to read adjacent process memory, and the only reliable mitigation is ensuring that cross-origin content never shares a renderer process.

The memory cost Google reported at launch: 10-13% more RAM in real workloads. A 2018 Chromium blog post by Charlie Reis (the engineer leading the implementation) put the figure at “about a 10-13% total memory overhead” on desktop and noted that the mobile rollout was staged differently due to tighter RAM constraints on Android.

By 2026, Site Isolation applies to:

  • All standard browsing (desktop, full enforcement since Chrome 67)
  • Extensions (each extension origin gets its own process)
  • Cross-origin iframes (Subframes)
  • Isolated web apps and origin trials using COOP/COEP headers

Site Isolation does NOT apply to same-site subframes. An <iframe> loading docs.google.com from mail.google.com (same eTLD+1) can share a renderer — Chrome applies a relaxed rule for same-site, different-subdomain contexts.

What Site Isolation Cannot Do

Site Isolation stops cross-process memory reads. It does not:

  • Reduce per-tab RAM (the renderer still runs JavaScript and renders the full DOM)
  • Protect against within-origin XSS attacks
  • Block fingerprinting via shared timing side-channels in the same process

If you see elevated per-tab RAM and want to measure it precisely: chrome://discards shows each tab’s memory state. Chrome Task Manager shows real-time per-process RAM.

V8 Heap Management and Garbage Collection

Each renderer process runs a V8 instance with its own heap. V8’s memory layout has two main generations:

New space (young generation): Where freshly allocated JavaScript objects land. Size: 1–8 MB (configurable). The Scavenger GC runs here frequently, copying surviving objects into old space. Short-lived objects (most event handlers, temporary DOM nodes, iteration variables) are collected here quickly.

Old space (old generation): Long-lived objects that survived multiple scavenge cycles. No fixed upper limit — V8 grows old space dynamically. The major GC (Orinoco) collects here. Major GC is incremental and concurrent: most marking work happens in background threads while JavaScript continues executing, with short stop-the-world pauses for finalization.

V8’s current GC infrastructure (as of Chrome 149, June 2026) is called Orinoco. It includes:

  • Concurrent marking (background threads mark live objects while main thread runs)
  • Parallel scavenging (multiple threads process the young generation)
  • Incremental marking (breaks full-heap scan into incremental steps to reduce jank)
  • Unified heap (V8’s heap and Blink’s DOM heap are partially unified for cross-language GC correctness)

The old performance.memory API (MemoryInfo) returns JS heap data only: usedJSHeapSize, totalJSHeapSize, JSHeapSizeLimit. These numbers exclude native memory allocated by Blink for DOM nodes, canvas buffers, and GPU textures — they typically undercount real renderer RAM by 30–60%. Chrome Task Manager’s “Memory Footprint” column is more accurate for diagnosing tab RAM usage.

The Tab Discard Mechanism

Tab discarding is how Chrome frees renderer memory without closing the tab. The same mechanism powers Chrome Memory Saver, SuperchargePerformance’s tab suspension, and the manual “Urgent Discard” button in chrome://discards.

The API call is chrome.tabs.discard(tabId), available to Chrome extensions and used internally by the browser itself. What happens at the system level:

  1. Chrome sends a signal to the renderer process for the target tab.
  2. The renderer serializes necessary state (scroll position is NOT saved — this is a known limitation) and terminates.
  3. The OS reclaims the renderer’s virtual address space immediately.
  4. The tab entry in the browser process retains: favicon, title, URL, and a flag marking it as discarded.
  5. When the user clicks the tab, Chrome spawns a fresh renderer and reloads from the network.

The per-tab RAM freed is approximately 90–95% of the renderer’s pre-discard footprint. The 5–10% residual is the browser-process overhead for the tab entry (a few KB to low MB). This is why “tab suspension saves 90–95% of each inactive tab’s RAM” is an accurate statement scoped to per-discarded-tab savings, not total Chrome session RAM.

Chrome Memory Saver vs. Timer-Based Suspension

Chrome Memory Saver (introduced Chrome 108, December 2022) uses the same chrome.tabs.discard() mechanism but with a memory-pressure gate: it waits for system RAM to become constrained before discarding. On a 16 GB machine, that pressure threshold may never trigger even with 30 tabs open.

Timer-based suspension, by contrast, discards on inactivity regardless of memory pressure. A 20-tab test over 30 minutes:

ConditionTotal Chrome RAMTabs Discarded
No suspension~2,400 MB0
Chrome Memory Saver (Maximum)~1,440–1,680 MB (−30–40%)8–12
Timer-based suspension (5 min)~600–720 MB (−70–75%)15–17

The 30–40% figure for Chrome Memory Saver aligns with Google’s own December 2022 announcement (“up to 40% and 10 GB less memory”) for sessions where pressure thresholds are repeatedly crossed.

Memory Leaks: What Actually Causes Them

A leak means memory grows and never drops, even after the trigger (opening a tab, running an animation, loading a doc) is removed. Chrome’s architecture creates several distinct leak patterns:

Zombie renderer processes. When a tab is closed, its renderer should terminate. JavaScript event listeners that hold references to DOM nodes, or extensions that communicate with tab content, can keep the process alive. The renderer appears in Task Manager as a “Renderer” row with no visible tab association. Ending it manually reclaims the memory.

JavaScript heap leaks. A long-running web app that continuously adds to a data structure without removing old entries will grow V8’s old space unboundedly. Common pattern: an analytics library appending to an in-memory event queue without flushing. Observable via the DevTools Memory tab — take a heap snapshot, interact with the app, take another snapshot, compare retained objects.

GPU process accumulation. After opening and closing multiple video tabs, the GPU process can accumulate texture memory that Chrome does not immediately release. On Windows 11, this often shows as 1–2 GB GPU Process RAM after a session with YouTube or Twitch. Ending the GPU process via Task Manager reclaims it; Chrome restarts the GPU process automatically within seconds.

Extension background pages. Manifest V2 extensions with persistent background pages run continuously regardless of tab activity. A background page that polls a remote server or processes messages can grow its V8 heap steadily over hours. Manifest V3 replaced persistent background pages with service workers that are supposed to terminate when idle — but a service worker can stay alive indefinitely if it holds an open message port or WebSocket.

Leak TypeVisible InReclaim Method
Zombie rendererTask Manager (Renderer, no tab)End Process
JS heap leakDevTools Memory tab, heap snapshotsClose/reload the tab
GPU accumulationTask Manager (GPU Process > 500 MB)End GPU Process
Extension backgroundTask Manager (Extension > 100 MB)Disable extension
Subframe/ad processesTask Manager (many Subframe rows)Block at network layer

The MemoryInfo API and Its Limits

performance.memory (the MemoryInfo API) has been in Chrome since the very early days as a non-standard V8 extension. It exposes three fields on any page:

performance.memory.usedJSHeapSize    // currently allocated JS objects
performance.memory.totalJSHeapSize   // total heap allocated (including free)
performance.memory.JSHeapSizeLimit   // maximum heap before V8 throws OOM

As of June 2026, this API still works in standard Chrome pages. However:

  • It only measures V8’s heap, not native Blink memory, GPU buffers, or canvas allocations. Real renderer RAM is typically 2–4× the usedJSHeapSize reading.
  • It is deprecated in cross-origin isolated contexts (pages served with Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp). These pages must use performance.measureUserAgentSpecificMemory() instead.
  • Values are quantized since Chrome 86: the API returns values rounded to the nearest 100 KB to reduce timing side-channel risk.

The replacement, performance.measureUserAgentSpecificMemory(), returns a breakdown by iframe and context. It requires cross-origin isolation and an explicit allow="attribution-reporting" permission on the page. For developer diagnostics on pages you control, it is more accurate. For general memory monitoring in a content script or extension, chrome.processes.getProcessInfo() (Processes API, requires the processes permission in your manifest) provides per-process memory accessible to extensions.

For diagnostic purposes outside of extension code: Chrome Task Manager (Shift + Esc) and chrome://discards give accurate, unquantized figures.

chrome://discards: The Diagnostic Tool Most Users Miss

chrome://discards is a first-party Chrome page that lists every open tab with its memory state, lifecycle state, and discard count. Fields to know:

ColumnWhat It Means
TitleTab title
StateActive, Visible, Hidden, Discarded, Frozen
Lifecycle StateMore granular: Loaded, Frozen, Discarded
Memory EstimateChromium’s internal estimate of tab renderer RAM
Reactivation ScoreChrome’s internal priority score for keeping the tab alive
Urgent DiscardButton to immediately discard the tab (frees renderer RAM)
Auto DiscardableWhether Chrome Memory Saver is allowed to discard this tab

The “Frozen” state is distinct from “Discarded”: a frozen tab has its JavaScript execution paused (reduces CPU) but keeps the renderer process in memory (does NOT free RAM). Chrome’s Energy Saver mode freezes tabs; Memory Saver discards them. The distinction matters when diagnosing whether freezing is actually helping your RAM situation.

Process Count at Scale

One often-overlooked aspect of Chrome’s architecture: the process count grows super-linearly with tabs. Each cross-origin iframe spawns its own Subframe process. A single news article can generate 5–15 processes depending on ad load. A realistic count for a developer workflow:

Tabs/ExtensionsApproximate Process Count
5 tabs (simple pages), 2 extensions12–18 processes
10 tabs (mixed content), 3 extensions25–40 processes
20 tabs (heavy apps + news), 5 extensions50–80 processes
30 tabs (heavy workload)80–120+ processes

Each process carries OS overhead: a memory-mapped page table, kernel bookkeeping, and Chrome’s own IPC channel infrastructure (Mojo). The inter-process communication overhead for a message between a renderer and the browser process is on the order of a few microseconds, but the cumulative overhead of managing 80+ processes is non-trivial on machines with under 8 GB RAM.

Chrome mitigates this with renderer process reuse: if you open two tabs to different pages on the same site (same eTLD+1), Chrome may put them in the same renderer process. This is an optimization, not a guarantee — Chrome uses a process-per-site-instance heuristic, and high memory pressure will push it toward fewer processes more aggressively.

Practical Diagnostics: When to Use Which Tool

ScenarioTool to Use
Identify which tab is using the most RAMChrome Task Manager (Shift+Esc)
Check if a tab is discarded or frozenchrome://discards
Find JavaScript heap leaks in a specific pageDevTools → Memory tab → Heap Snapshots
Measure JS heap from extension codechrome.processes.getProcessInfo()
Measure JS heap from page codeperformance.measureUserAgentSpecificMemory()
Diagnose GPU process bloatTask Manager → GPU Process row
Kill a zombie rendererTask Manager → End Process
Bulk-discard idle tabschrome://discards → Urgent Discard, or tab suspension extension

When Architecture Becomes a Problem

Most users never need to think about any of this — Chrome’s defaults work acceptably for sessions with under 10 tabs. The architecture becomes a visible problem when:

  • High tab count (20+): each tab’s renderer adds 80–300 MB; 30 tabs can reach 4–6 GB before Memory Saver activates on a machine not under memory pressure.
  • Ad-heavy pages: Subframe processes multiply. Ten tabs on news sites can generate 60+ Chrome processes, each consuming OS-level overhead beyond the raw renderer RAM.
  • Long sessions: zombie processes and GPU accumulation compound over hours. A Chrome session open for 24 hours on a content-heavy workflow is rarely at the same RAM footprint as a fresh launch.
  • Memory-intensive web apps: Figma, Miro, and complex Google Sheets documents can push individual renderer heaps past 500 MB. These apps allocate large ArrayBuffers and canvas textures that sit outside V8’s main GC scope.
  • Many extensions: each extension’s background service worker or persistent background page adds 30–150 MB.

For the first two categories, tab suspension is the practical lever: discarding the renderer process via chrome.tabs.discard() removes the RAM regardless of why it was high. For the last three, the fix is narrower: close and reopen the specific app tab, end the GPU process, or disable the heavy extension.


For RAM savings comparisons, see Chrome Memory Saver Reviewed: Does It Save Enough? and Tab Suspender vs. Chrome Memory Saver. For Windows-specific leak diagnosis, see Fix Chrome Memory Leaks on Windows 11.

Frequently Asked Questions

How does Chrome allocate memory per tab in 2026?
As of June 2026, each Chrome tab runs in its own renderer process under Site Isolation, typically consuming 80–300 MB depending on content. A simple Wikipedia page sits around 80 MB; YouTube with autoplay uses 200–300 MB. Chrome also runs a browser process (~150–300 MB), a GPU process (~100–500 MB), and a Network Service process (~50–100 MB). A session with 20 tabs realistically uses 2–4 GB of RAM total.
What is Site Isolation and how much RAM does it use?
Site Isolation (enabled by default since Chrome 67, May 2018) places every site origin into its own renderer process. This prevents Spectre-class attacks from reading memory across origins. Google's own data on the Chromium blog (2018) put the overhead at 10-13% more RAM in real workloads. On a 4 GB machine with 10 tabs, that is roughly 50-130 MB extra for the security benefit.
What is V8's garbage collector called in Chrome 2026?
As of Chrome 149 (June 2026), V8 uses a generational garbage collector called Orinoco. It runs major GC (full heap collection) concurrently in a background thread, and minor GC (young generation scavenging) incrementally. The young generation (new space) is typically 1–8 MB; the old generation heap grows dynamically. V8 exposes approximate heap usage via the legacy performance.memory API (JSHeapSizeLimit, usedJSHeapSize, totalJSHeapSize), though that API is deprecated in cross-origin isolated contexts.
Does chrome.tabs.discard() free RAM immediately?
Yes. When chrome.tabs.discard(tabId) is called, Chrome terminates the renderer process for that tab and releases its memory back to the OS. The tab remains visible in the tab strip and reloads from the network when clicked. Chrome Task Manager (Shift+Esc) shows 0 KB for the discarded tab's process immediately after. The browser process retains a few KB for the tab entry (favicon, title, URL). This is why tab suspension frees 90–95% of each inactive tab's RAM — the renderer is entirely unloaded.
How many processes does Chrome run with 10 tabs open?
As of June 2026, Chrome with 10 tabs typically runs: 10 renderer processes (one per site origin under Site Isolation), 1 browser process, 1 GPU process, 1 Network Service process, 1 process per active extension, and multiple Subframe processes for embedded iframes. A realistic 10-tab session with 3 extensions can generate 20–35 Chrome processes. Check chrome://discards or Shift+Esc (Chrome Task Manager) to see the exact count on your machine.
What is the MemoryInfo API and is it still available?
performance.memory (the MemoryInfo API) exposes JSHeapSizeLimit, totalJSHeapSize, and usedJSHeapSize. As of June 2026, it is still accessible in standard (non-cross-origin isolated) Chrome pages, but it is deprecated and may be restricted further in future releases. For accurate tab-level memory measurement, Chrome Task Manager or chrome://discards are more reliable. The replacement API, performance.measureUserAgentSpecificMemory(), requires cross-origin isolation (COOP+COEP headers) to use.

Don't miss the next release

Be first to know when we ship something new.

Related Articles