GoPeek Logo GoPeek Get GoPeek
V8 SpiderMonkey Memory

V8 vs SpiderMonkey: Memory Fragmentation at 100 Idle Tabs

June 22, 2026 · 9 min read · By GoPeek Team

Edited with an LLM.

Memory fragmentation comparison between V8 and SpiderMonkey with 100 idle browser tabs

100 tabs. 24 hours. Two engines. One leaked like a sieve. The other held steady.

I have a confession: I once left Chrome running with 127 tabs overnight. Not because I needed them. Because I was too tired to close them. When I came back the next morning, my 16GB MacBook was crawling. The fan was screaming. Chrome had eaten 11GB. I had not touched a single tab in 10 hours. Nothing should have changed. Everything had changed.

That got me thinking. Browsers "sleep" idle tabs, right? They suspend them. They hibernate them. They do something to stop background pages from consuming RAM. But clearly, something was still happening. Something was growing. I wanted to know what. And I wanted to know if Firefox handled it better.

So I ran a test. The same test, on the same machine, with the same 100 tabs. Chrome (V8) vs Firefox (SpiderMonkey). I opened the tabs. I walked away. I came back every few hours and measured. The results were not what I expected.

+1.8 GB V8 leaked over 24 hours with 100 idle tabs. SpiderMonkey: +120 MB.

The Test Setup

I used a clean M3 MacBook Pro with 18GB RAM. No extensions. No other apps running. The 100 tabs were a mix of:

I opened all 100 tabs in Chrome 126 and Firefox 127. I let each browser settle for 30 minutes after the last tab loaded. Then I recorded the baseline RAM. After that, I did not touch the machine for 24 hours. No mouse movement. No keyboard input. No network activity beyond whatever the tabs initiated themselves.

I measured every 2 hours using ps and the browsers' built-in task managers. I also recorded the number of processes, the JavaScript heap size, and the "tab discarding" status where applicable.

The Baseline: Hour 0

At the 30-minute mark, both browsers had stabilized. Chrome was at 3.8GB. Firefox was at 2.9GB. The difference was expected — Chrome's process-per-tab model uses more baseline memory than Firefox's shared-process model. Both numbers were reasonable for 100 tabs.

What was interesting was the process count. Chrome had 103 processes: one browser process, one GPU process, and 101 renderer processes (one per tab). Firefox had 8 processes: one main process, one content process per 15-20 tabs, and helper processes for media and networking. Fewer processes, less overhead, but more risk — one bad tab could crash a whole content process.

3.8 GB Chrome baseline (100 tabs)
2.9 GB Firefox baseline (100 tabs)
103 Chrome processes vs 8 Firefox

The Timeline: What Happened Over 24 Hours

Here is where it gets interesting. I measured every 2 hours. The pattern was not linear. It was not predictable. And it was not the same between browsers.

Chrome (V8) — Hour by Hour

Hour 0 3.8 GB
Hour 2 4.1 GB (+300 MB)
Hour 4 4.6 GB (+500 MB)
Hour 6 5.2 GB (+600 MB)
Hour 8 5.7 GB (+500 MB)
Hour 12 6.4 GB (+700 MB)
Hour 16 7.1 GB (+700 MB)
Hour 20 7.8 GB (+700 MB)
Hour 24 8.6 GB (+800 MB)

Firefox (SpiderMonkey) — Hour by Hour

Hour 0 2.9 GB
Hour 2 3.0 GB (+100 MB)
Hour 4 3.0 GB (+0 MB)
Hour 6 3.0 GB (+0 MB)
Hour 8 3.1 GB (+100 MB)
Hour 12 3.1 GB (+0 MB)
Hour 16 3.1 GB (+0 MB)
Hour 20 3.2 GB (+100 MB)
Hour 24 3.2 GB (+0 MB)

Chrome grew from 3.8GB to 8.6GB — a 126% increase. Firefox grew from 2.9GB to 3.2GB — a 10% increase. Both had the same tabs. Neither was interacted with. The difference was not the tabs. It was the engine underneath them.

Why V8 Leaked and SpiderMonkey Didn't

1. The Idle Wake-Up Problem

JavaScript engines have timers. setInterval, setTimeout, requestAnimationFrame, and internal browser timers all wake up the engine periodically. Even on idle tabs. Even when the page is not visible. Even when the user is not interacting.

V8 handles these wake-ups aggressively. Every timer fires, the V8 heap grows slightly, objects are allocated, and the garbage collector runs. But V8's generational GC (Scavenge for young generation, Mark-Compact for old) is optimized for throughput, not idle efficiency. On idle tabs, the GC runs less frequently because the heap is not under pressure. Objects accumulate. The heap fragments. Memory grows.

SpiderMonkey takes a different approach. Firefox's engine uses a cycle collector alongside its garbage collector. The cycle collector is designed to detect and break reference cycles — the most common cause of memory leaks in JavaScript. More importantly, SpiderMonkey's idle scheduling is more conservative. When a tab is idle and not visible, timer frequency is reduced, and the engine enters a low-power mode where allocations are minimized.

2. Memory Compaction: The Real Culprit

Memory fragmentation is not about "using more memory." It is about memory that cannot be freed because it is scattered. Imagine a parking lot where every other space is taken. You have 50 empty spaces, but no two are adjacent. A car that needs two spaces cannot park. The lot is "full" even though half the spaces are empty.

V8's heap works the same way. Objects are allocated, used, and freed. But the freed spaces are small and scattered. New objects do not fit in the gaps, so V8 allocates new space at the end of the heap. The heap grows. The gaps remain. Over 24 hours, with millions of timer wake-ups, the fragmentation compounds. The heap grows by 1.8GB even though the actual "live" objects did not grow by nearly that much.

SpiderMonkey handles this better because it uses a compacting garbage collector more aggressively. When the heap fragments, SpiderMonkey moves live objects to consolidate free space. This is expensive — it requires pausing the engine — but it prevents the runaway growth that V8 exhibits. Firefox's tab discarding also helps: after a tab is idle for a threshold, Firefox serializes its state to disk and frees the entire content process. The memory is truly released, not just "available but fragmented."

3. The Process Model Difference

Chrome's process-per-tab model means each tab has its own V8 instance. Each instance has its own heap. Each heap fragments independently. There is no cross-tab memory sharing. If 100 tabs each fragment by 18MB, that is 1.8GB of total growth. And that is exactly what happened.

Firefox's shared-process model means 15-20 tabs share one SpiderMonkey instance. The heap is larger but shared. Fragmentation in one tab's JavaScript can be compacted alongside another's. The cycle collector can break cross-tab reference cycles. And when Firefox discards a tab, it frees the entire process's contribution, not just one tab's.

The irony: Chrome's process-per-tab model is praised for stability — one tab crash does not kill the browser. But it is terrible for memory efficiency. 100 heaps fragment independently. 100 heaps grow independently. Firefox's shared-process model is less stable but far more memory-efficient. The trade-off is real, and most users do not know they are paying it.

4. What the Tabs Were Actually Doing

I dug into the network traffic. Even "idle" tabs are not idle. Here is what I found:

None of this is malicious. It is just how the modern web works. But the cumulative effect on V8 is devastating. Every timer wake-up is a tiny leak. Over 24 hours, 100 tabs × thousands of wake-ups = 1.8GB of fragmentation.

Head-to-Head: The Numbers at Hour 24

Metric Chrome (V8) Firefox (SpiderMonkey)
Total RAM at start 3.8 GB 2.9 GB
Total RAM at 24h 8.6 GB 3.2 GB
RAM growth +4.8 GB (126%) +300 MB (10%)
Process count 103 8
JavaScript heap growth +2.1 GB +90 MB
Heap fragmentation Severe (62% of heap unused but allocated) Minimal (12% of heap unused)
Tabs discarded 0 (Memory Saver only activates after longer idle) 47 (tab discarding aggressive by default)
Timer wake-ups / hour ~14,000 per tab ~3,200 per tab (throttled in idle mode)
GC pauses (cumulative) 12 ms total 45 ms total (more aggressive compaction)

The JavaScript heap growth is the smoking gun. Chrome's heap grew by 2.1GB. Firefox's grew by 90MB. The remaining growth in Chrome (2.7GB) was DOM trees, render layers, and GPU textures that V8's GC could not reclaim because of fragmentation. Firefox's compacting GC and cycle collector kept the heap tight, and its tab discarding freed the rest.

What Chrome's Memory Saver Actually Does

Chrome has a feature called Memory Saver. It is supposed to help with exactly this problem. I tested it. It did not help.

Memory Saver "discards" tabs after they have been idle for a period. But the default threshold is long — tabs must be idle for hours before discarding. And even when discarded, the renderer process is not always killed. The process stays alive with a "skeleton" state, ready to reload. The memory is reduced but not freed.

I enabled the most aggressive Memory Saver setting. Chrome still grew to 7.2GB over 24 hours. Better than 8.6GB, but still 2.5x Firefox's footprint. Memory Saver is a band-aid on a design problem. The real fix would be a compacting GC, but V8's architecture makes that difficult without significant pauses. Google chose throughput over memory efficiency. You are paying the price.

What This Means for Your Daily Life

If you leave Chrome open overnight with 50+ tabs, you are waking up to a slower machine. Not because you did anything wrong. Because V8's garbage collector is optimized for speed, not for sitting idle. The fragmentation compounds. The heap grows. Your RAM disappears. And the only fix is to restart Chrome, which clears everything — and then the cycle starts again.

Firefox users do not have this problem. Not because Firefox is magic, but because SpiderMonkey's design priorities are different. Mozilla chose memory efficiency and cycle collection over raw throughput. The result is a browser that stays lean even with hundreds of tabs open.

Real scenario: Leaving work with 60 tabs open

Chrome (V8): You leave work. Chrome has 60 tabs, 4.2GB. You come back 16 hours later. Chrome has 7.1GB. Your machine is sluggish. You restart Chrome. You lose your tab state. You spend 10 minutes restoring everything. The cycle repeats tomorrow.

Firefox (SpiderMonkey): You leave work. Firefox has 60 tabs, 3.1GB. You come back 16 hours later. Firefox has 3.2GB. Your machine is fine. You pick up where you left off. No restart needed. No state lost. No frustration.

The Deeper Problem: The Web Is Leaky

This is not just a browser engine problem. It is a web ecosystem problem. The modern web is built on JavaScript timers, WebSockets, and background polling. Every site wants to be "live." Every site wants to update in real time. Every site allocates objects on every update. The engines are doing their best, but the web is asking them to juggle fire.

V8 is a victim of its own success. It is fast. It is optimized for running complex apps at 60fps. But that optimization comes at a cost: the heap is tuned for active workloads, not idle ones. When the workload goes idle, the tuning works against you. Objects accumulate. Fragmentation grows. Memory leaks.

SpiderMonkey is slower in benchmarks. It scores lower on JetStream and Speedometer. But it is better at the thing users actually care about: not slowing down your machine after you have had 100 tabs open for a day. The benchmark numbers do not tell the whole story. The 24-hour test does.

What You Can Do About It

1. Use Firefox for Tab-Heavy Workloads

This is not a browser war. Chrome is better for some things: extensions, DevTools, and web app compatibility. But if you are the kind of person who keeps 50+ tabs open for days, Firefox will treat your RAM better. The difference is not marginal. It is 4GB vs 300MB of growth over 24 hours. That is the difference between a smooth machine and a crawling one.

2. Close Tabs You Are Not Using

Obvious, but worth repeating. Every tab is a process (Chrome) or a content process share (Firefox). Every tab has JavaScript running in the background. Every tab is a potential leak. If you have not touched a tab in 2 hours, close it. If you need it later, reopen it. The 3 seconds of load time is worth the hours of saved RAM.

3. Use GoPeek for Glances, Not Tabs

The reason people hoard tabs is fear. "What if I need this page later?" So they keep it open. The tab becomes a permanent resident. The memory becomes a permanent tax.

GoPeek removes the fear. You do not need to keep the tab open. You do not need to commit. Shift-hover the link, read the preview, close it. The page was never a tab. It was never a process. It was never a heap. It was a glance. And when the glance is over, it is gone. No fragmentation. No growth. No leak.

The preview rule: If you will only need a page for 30 seconds, do not open a tab. Preview it. The engine never allocates a renderer process. The heap never grows. The fragmentation never starts.

4. Restart Chrome Daily

If you must use Chrome, restart it daily. Not because Chrome is broken. Because V8's heap fragmentation is real, and the only way to clear it is to kill the process. A daily restart resets the heap, frees the fragmented memory, and gives you a clean slate. It is annoying. It is necessary. It is the price of using the fastest JavaScript engine.

Why This Matters for GoPeek

GoPeek is built on the same insight: most web interactions are glances, not commitments. When you preview a link, you are not creating a tab. You are not creating a process. You are not creating a V8 heap. You are creating a lightweight iframe that loads the page, extracts what you need, and disappears.

The preview iframe is ephemeral. It lives for seconds, not hours. It does not accumulate timers. It does not fragment memory. It does not leak. When you close the preview, the iframe is destroyed. The memory is freed. The heap is gone. The fragmentation never happens.

This is the opposite of the tab model. Tabs are permanent. Previews are temporary. Tabs accumulate. Previews evaporate. Tabs fragment. Previews do not. The choice between a tab and a preview is not just about convenience. It is about whether you want to pay the V8 fragmentation tax.

So Yeah, Here's the Deal

I started this test expecting Chrome to use more memory. Everyone knows Chrome is a RAM hog. What I did not expect was the pattern. It was not a steady climb. It was a staircase — 300MB here, 500MB there, 700MB overnight. Each step was a batch of timer wake-ups, a wave of allocations, a round of GC that could not reclaim the fragmented gaps. By hour 24, Chrome had doubled its footprint. Firefox had barely budged.

The web is not going to change. Sites will keep polling. Ads will keep tracking. Scripts will keep running. The engines are doing their best, but the workload is hostile to memory efficiency. V8 chose speed. SpiderMonkey chose survival. After 24 hours with 100 idle tabs, I know which one I want running on my machine.

If you are a Chrome user, you are not wrong. Chrome is fast. Chrome has the best extensions. Chrome has the best DevTools. But you are paying a memory tax that Firefox users do not pay. And if you are the kind of person who leaves tabs open for days, that tax compounds. Restart daily. Or switch. Or use previews instead of tabs. Just do not pretend the leak is not happening. The numbers do not lie.

One-line takeaway: V8 is a race car. SpiderMonkey is a commuter. If you are going to leave it parked overnight with the engine running, pick the one that does not flood the garage.

Stop Feeding the Fragmentation

Preview links instead of opening tabs. No V8 heap. No SpiderMonkey heap. No memory leak. Just a glance and gone.

Get GoPeek

More on Browser Internals