"Unused RAM Is Wasted RAM" Is Not An Excuse For Chrome


The Reply You Always Get

Open Task Manager. Chrome is sitting on 6 GB across thirty processes. You complain about it in some thread, and within five minutes someone shows up with the line:

“Unused RAM is wasted RAM. Relax. It’s supposed to use it.”

Is that actually a defense of Chrome? Or is it a true sentence about something else, wearing a Chrome costume?

To be honest, it’s the second one. The slogan is real. It is also one of the most misapplied facts in computing. It was never a statement about applications. It was a statement about the operating system’s own disk cache, and the moment you point it at Chrome’s heap it stops being true in any useful way.

So this post is not “Chrome bad” and it is not “Chrome fine, stop whining.” It’s narrower and more annoying than either:

"unused RAM is wasted RAM" = true for the OS page cache
                           = a bad excuse for an app holding gigabytes of resident memory

The reason it’s a bad excuse is the whole interesting part, and it lives in how memory is actually allocated and accounted on Linux, Windows, and macOS. That is where we’re going.

Where The Slogan Actually Comes From

The phrase has a canonical home: a tiny single-page site called Help! Linux ate my RAM! that exists purely to calm down people who ran free, saw almost no memory available, and panicked.1

The point it makes is correct. Linux deliberately fills otherwise-idle RAM with the page cache: copies of file data read from or written to disk, kept around in case you need them again.2 If you just read a 500 MB file, that 500 MB sits in RAM afterwards. Your “used” memory goes up. Nothing is wrong. The kernel is using a resource that would otherwise sit there doing nothing, to make your next read instant instead of a disk seek.

And here is the property that makes the slogan true:

page cache is CLEAN and FILE-BACKED
-> the data already exists on disk
-> the kernel can drop those pages instantly, for free, with zero I/O
-> the instant an app actually needs the RAM, it gets it

That last line is the whole slogan. The cache is “free” because it is reclaimable on demand.2 It is RAM held with no strings attached. Holding it costs you nothing, and releasing it costs you nothing. Under those conditions, yes, obviously, unused RAM is wasted RAM. Cache it.

The trouble starts when people quietly swap out “the OS’s reclaimable file cache” and swap in “any program that happens to be using a lot of memory.” Those are not the same thing. They are barely even related.

Cache RAM And App RAM Are Not The Same Animal

There are two broad kinds of memory a system tracks, and the difference between them is the hinge this entire argument turns on.

File-backed (page cache)Anonymous (an app’s heap)
What it isCopies of on-disk filesA program’s own allocations: heap, stack, JS objects
Backing storeThe file already on diskNothing, unless you swap
Reclaim costFree. Drop the clean page, doneExpensive. Must write it to swap or compress it first
Is it “wasted” when idle?No, it’s a free cacheMaybe. It’s a real claim on RAM

Chrome’s memory is overwhelmingly the right-hand column. Your tabs, the JavaScript heaps, the DOM, the decoded images, the rendering buffers: that’s anonymous memory.2 It is not a convenient copy of something that already lives on disk. It is the only copy. There is no file to drop it back to.

So when the OS wants that RAM back, it cannot just discard Chrome’s pages the way it discards file cache. It has to write them somewhere first: to swap on Linux, to the pagefile on Windows, or into a compressed region. That costs CPU and it costs I/O.

flowchart TD
    P["OS needs a physical page back"] --> Q{"What kind of page?"}
    Q -->|"Clean, file-backed (page cache)"| R["Drop it. The copy still lives on disk."]
    R --> S["Reclaimed for free. Zero I/O."]
    Q -->|"Anonymous (app heap, e.g. a Chrome tab)"| T["Write it out first: swap or compress"]
    T --> U["Reclaimed, but it cost CPU and I/O."]

That is the sleight of hand in one sentence:

the slogan is true because the cache costs nothing to reclaim
an app's heap costs real work to reclaim
therefore the slogan does not transfer to the app

Cache RAM is a houseguest who leaves the instant you need the room. App RAM is a tenant with a lease. Calling both of them “just using RAM efficiently” is how the argument goes wrong.

The Number You’re Reading Is The Wrong Number

Part of why this slogan survives is that the everyday tools encourage you to read the wrong number.

On Linux, free shows you MemFree, and people read that as “how much room I have left.” It isn’t. The number that actually answers “how much can I open before things hurt” is MemAvailable, and it is deliberately different: it includes the reclaimable page cache and slab that MemFree ignores.3 A box can show almost no MemFree and still have tons of MemAvailable, because most of “used” is reclaimable cache. The slogan is gesturing at exactly this gap. It just forgets that the gap is made of cache, not of Chrome.

The vendors already know “used” is the wrong metric, and they redesigned their tools around it.

macOS is the cleanest example. Open Activity Monitor on a recent macOS and the headline isn’t “Memory Used.” It’s Memory Pressure, a green / yellow / red graph.4 Apple’s own guidance is that green means your RAM is being used efficiently even when it looks almost full, because a big chunk of that fullness is cached files and compressed pages it can reclaim. The signal that matters is pressure, not occupancy. They are telling you, in the UI, that “how full is the bar” is not the question.

That is the irony of the slogan. The people repeating it think they’re defending high memory usage. The OS vendors agree with them so hard that they stopped showing usage as the primary number at all. But notice what that buys Chrome: nothing. Pressure being green is a statement about reclaimable memory. Chrome’s resident heap is the part that does not reclaim for free.

Allocating Memory Is Not Using Memory

Now it gets worse for the slogan, because even the word “using” is doing something sneaky.

When a program allocates memory, nothing physical happens. A call like malloc (which turns into mmap or brk underneath) reserves a range of virtual address space and returns immediately. No physical RAM is assigned. Not one page.5

The physical page only gets attached the first time you actually touch that address. That touch triggers a page fault, the kernel finds a real physical frame, maps it in, and only then does your “used RAM” tick up. This is demand paging, also called lazy allocation, and it is the default behaviour on every modern OS.52

flowchart LR
    A["malloc(1 GB)"] --> B["Reserve virtual address space. Return instantly."]
    B --> C["0 physical pages used"]
    C --> D{"First write to a page?"}
    D -->|"Yes"| E["Page fault: map one 4 KB physical frame"]
    E --> F["That page is now resident"]
    D -->|"Never touched"| G["Never costs a byte of physical RAM"]

This breaks the slogan from the other side. “Unused RAM is wasted RAM” assumes that more allocation means more good, productive use of memory. But a program can allocate enormous amounts and physically use almost none of it, because untouched allocations cost zero physical RAM. The map in your head (“allocated = used = filling RAM = good”) is just wrong. Allocated is a promise. Used is a touch. The task manager shows you roughly the touches, not the promises.

So already we have two different “used” numbers diverging:

virtual size     = what the app asked for (promises, mostly free)
resident size    = what is actually in physical RAM right now (the real claim)

The slogan never says which one it means. That ambiguity is load-bearing for it. Pin it down to either definition and it falls apart.

Two Operating Systems, Two Philosophies Of The Lie

Here is the part Chrome’s defenders never reach, and it’s the most interesting part: what a memory allocation costs the system is not even the same across operating systems. Linux and Windows made opposite bets. The slogan flattens both into “used = good,” which means it is wrong in two different ways at once.

Linux: overcommit and the OOM killer

Linux is an optimist. By default it overcommits: it will happily hand out more virtual memory than it can physically back, betting that programs allocate way more than they ever touch (which, per the previous section, is usually true).6 The behaviour is controlled by vm.overcommit_memory:

0 = heuristic (default): allow reasonable overcommit, reject the wildly unreasonable
1 = always: never refuse an allocation, promise everything
2 = strict: never promise more than swap + a configurable fraction of RAM

In the default mode, malloc almost never fails. Linux says yes to everyone. The slogan is practically a description of Linux’s allocator personality: hand out the RAM, assume it’ll be fine.

But a bet needs a backstop for when it loses. What happens when all those cheerfully-granted promises get called, the processes actually touch their pages, and RAM plus swap genuinely runs out? Linux invokes the OOM killer: the kernel picks a process and kills it to reclaim memory.7 That is the cost hiding behind “just use the RAM.” It is not a free lunch deferred forever. It is a free lunch with a bouncer who, when the room is finally full, throws someone out the window. Often that someone is the biggest memory user in the room. Often that is Chrome.

Windows: reserve, commit, and the commit limit

Windows is an accountant. It does not overcommit the same way. Memory goes through two explicit stages:8

RESERVE = claim a range of address space, no resources attached
COMMIT  = back this range with "memory charges" against RAM + pagefile

The crucial thing is commit charge. When you commit memory on Windows, even before you touch it, it is charged against a system-wide commit limit. And Microsoft defines that limit precisely: “the system commit memory limit is the sum of physical memory and all page files combined.”9 Every committed page is a “promise” counted against that total, and if the total commit charge hits the limit, new commits fail. No optimism, no overcommit, no OOM lottery. The allocation just gets refused.

Now, Windows is still lazy about physical residency, same as everyone. Microsoft is explicit: a committed page has its charge reserved up front, but “the system initializes and loads each committed page into physical memory only during the first attempt to read or write to that page.”10 So commit charge is not resident memory. It’s the accounted promise. The pages still don’t occupy RAM until touched.

But the accounting is real and finite. You can have free physical RAM and still fail to commit, because the commit limit (RAM + pagefile) is exhausted by promises. That is a completely different failure mode from Linux, and the slogan has nothing to say about it. “Unused RAM is wasted RAM” is meaningless to a Windows box that just refused an allocation while showing 4 GB free, because the thing that ran out wasn’t RAM. It was commit.

Same slogan, two different costs

The same allocation request walks two completely different roads depending on the OS:

flowchart TD
    R["Program requests memory"] --> OS{"Which OS?"}
    OS -->|"Linux (overcommit)"| L1["Grant it. Promise more than physical RAM."]
    L1 --> L2["Physical pages assigned on first touch"]
    L2 --> L3{"RAM + swap exhausted when touched?"}
    L3 -->|"Yes"| L4["OOM killer terminates a process"]
    L3 -->|"No"| L5["Fine"]
    OS -->|"Windows (commit charge)"| W1["Charge the commit against RAM + pagefile"]
    W1 --> W2{"Commit limit exceeded?"}
    W2 -->|"Yes"| W3["Allocation fails, up front"]
    W2 -->|"No"| W4["Physical pages assigned on first touch"]

Put them side by side and the slogan’s emptiness is obvious:

Linux (default)Windows
Allocation policyOvercommit: promise more than you haveStrict commit: promise is charged up front
Does malloc/commit fail under pressure?Rarely. It says yesYes, when commit limit is hit
Physical page assigned when?First touch (demand paging)First touch (demand paging)
The backstop when it goes wrongOOM killer terminates a processCommit fails; app handles or crashes
What “used all the RAM” can cost youA process gets killedNew allocations refused

“Used = good” does not survive contact with either column. On Linux the cost of pushing memory is a kill. On Windows it’s a hard accounting wall. The phrase pretends those costs don’t exist.

What It Actually Costs When Pressure Hits

The slogan’s defenders are implicitly right about one thing: while there is headroom, holding RAM is genuinely cheap. The problem is what happens at the moment of contention, which the slogan never reaches.

When real pressure hits, no modern OS just gives up. It works harder to make room, and that work is the cost.

  • macOS compresses inactive pages in RAM before it ever swaps. Activity Monitor literally has a “Compressed” figure next to “Cached Files.”4 Compressing and decompressing pages trades CPU cycles to avoid touching the disk.
  • Windows trims pages out of a process’s working set (the pages of that process currently resident in physical RAM) and pages them to the pagefile. Getting them back is a hard page fault: the CPU stalls while the page is read back from the backing store.11 Modern Windows also compresses pages in RAM before paging them out, same idea as macOS.
  • Linux compresses (zram / zswap) and swaps anonymous pages out to make room, and in the worst case reaches for the OOM killer.7

It’s a ladder, and every rung costs more than the last:

flowchart LR
    A["Memory pressure rises"] --> B["Drop clean file cache (free)"]
    B --> C["Compress inactive pages in RAM (CPU)"]
    C --> D["Swap / pagefile to SSD (hard page faults)"]
    D --> E["Out of room: OOM kill / commit failure"]

Every one of these is the system spending CPU and I/O to walk back a memory claim that the slogan told you was free. And the latency gap is brutal. A RAM access is on the order of ~100 nanoseconds. Pulling a page back from even a fast NVMe SSD is on the order of tens of microseconds. That is a factor of a few hundred, easily. The page you “used efficiently” is now a multi-microsecond stall the first time you scroll back to that tab.

RAM hit:        ~100 ns
hard page fault from SSD: ~tens of microseconds  (hundreds of times slower)

So the honest version of the slogan is conditional: holding RAM is free while there is no pressure, and the bill arrives precisely when there is. An app that holds a lot of resident memory is fine right up until the exact moment it isn’t, and that moment is not visible in the “it’s fine, look how efficient” screenshot.

Okay, So Why Is Chrome Actually This Heavy?

Now that we’ve dismantled the excuse, let’s be fair to Chrome, because the answer is not “it’s badly written” or “it leaks.” Chrome is heavy on purpose, and the reason is a security decision you actually want.

Chrome runs as many separate OS processes: one per tab-ish unit, plus the browser, GPU, network, and extension processes. The Chromium docs give three reasons: stability (one renderer crashing doesn’t take down the others), performance (sites run in parallel “at the cost of some memory overhead for each process”), and security.12

That last one is the big one. It’s called Site Isolation, and it exists because of Spectre and Meltdown. Once those transient-execution attacks showed that a process could read memory it wasn’t supposed to via microarchitectural side channels, the Chromium team concluded, in their words, that “it is no longer safe to render documents from different web sites in the same process.”12 So Chrome locks each renderer to a single site. Your bank tab and the sketchy ad iframe do not share an address space.

Process isolation is not free. Each process carries its own overhead, and the docs say so directly: the parallelism comes “at the cost of some memory overhead for each process.”12 So a big part of Chrome’s footprint is not waste. It is the price of not letting one website read another website’s memory. That is a trade you should want made.

Chrome's RAM is not (mostly) a leak
it is the cost of: per-site process isolation as a defense against Spectre-class attacks

This is the part the slogan crowd and the Chrome-haters both miss. It isn’t “Chrome wastes RAM” and it isn’t “all that RAM is free, relax.” It’s “Chrome spends RAM buying you security, and that spend has real costs under pressure.” Both halves are true.

And The Task Manager Number Is Lying To You Anyway

Even if you want to measure Chrome’s footprint honestly, the obvious method (sum up all those processes in Task Manager) overcounts. Badly.

The processes share memory. Shared libraries, common read-only data, and other mapped regions are physically resident once but appear in every process that maps them. Chromium’s own memory docs define a shared page as one “whose contents could be shared with other processes,” as opposed to a private page only that process can modify.13 If you naively add up each process’s resident size, you count that shared region once per process. The grand total is inflated.

The honest metric is PSS, Proportional Set Size. PSS splits each shared region across everyone mapping it: a page shared by N processes counts as 1/N in each. As the Chromium docs put it, PSS “counts 1/Nth of the resident size, where N is the number of other processes that have page faulted the region,” which has “the nice property of being additive across processes.”13 Add up PSS and you get something close to Chrome’s real physical footprint, without the double-counting.

So the scary number in Task Manager is itself an overstatement. Chrome’s true resident footprint is lower than the sum of its processes suggests. Which, to be clear, cuts against the haters, not for the slogan. The slogan is still wrong about reclaimability. Chrome is just also not quite as fat as the naive total implies.

Chrome Is Not Naively Hoarding, Either

If holding RAM were genuinely free, Chrome would just hold it all and never give anything back. It doesn’t. And the fact that Google built machinery to give memory back is itself the strongest evidence that “unused RAM is wasted RAM” is not how they actually think.

Two pieces of that machinery are worth naming.

First, Chrome ships its own memory allocator, PartitionAlloc. It does not just free() back into a heap and sit on the address space forever. When every object in a region is freed, PartitionAlloc “returns the physical memory to the operating system, but continues to reserve the region of address space.”14 That is exactly the distinction this whole post is about: it hands the physical pages back to the OS (real reclaim) while keeping the cheap virtual reservation for reuse. It even has a PurgeMemory() that runs periodically and under low-memory pressure to decommit empty regions.14 Chrome’s allocator is actively trying to minimize its resident footprint. That is the opposite of “hold everything, RAM is free.”

Second, Memory Saver. Chrome will deactivate tabs you haven’t touched and reload them when you come back, with Moderate / Balanced / Maximum modes controlling how aggressive it is.15 When Google announced it, they claimed it cuts Chrome’s memory use by “up to 40%” and frees “up to 10GB.”16 You don’t build and ship a 40% memory-reduction feature for a resource you genuinely believe is wasted when unused. Google shipped it because at scale, on real machines with other apps, holding all that RAM was not, in fact, free. Chrome even surfaces per-tab memory if you hover a tab, so the cost is legible to you.17

PartitionAlloc: returns physical pages to the OS, keeps the address reservation, purges under pressure
Memory Saver:   discards inactive tabs to claw back resident memory ("up to 40%")

Both features only make sense if resident RAM is a real, finite, worth-reclaiming resource. Which is the thing the slogan denies.

The Verdict

So, is unused RAM wasted RAM?

As a statement about the OS page cache: yes, completely. The cache is clean, file-backed, and reclaimable for free, so the kernel should absolutely fill idle RAM with it. That’s good engineering and you should not panic when free looks full or Activity Monitor’s bar is near the top with the pressure graph green.

As a defense of an application sitting on gigabytes of resident memory: no. It’s a bad argument, and now we can say exactly why it’s bad:

it conflates reclaimable cache (free to release) with an app's heap (expensive to release)
it conflates allocated (a promise) with resident (a real claim)
it ignores that "the claim" means different things on Linux (overcommit + OOM) and Windows (commit charge)
it hides the cost, which is real but only shows up under pressure: compression, swap, hard faults, a kill, a refused commit

The cost of holding RAM isn’t zero. It’s deferred, and it lands at the worst possible time: the moment something else needs memory. “Unused RAM is wasted RAM” is the sentence you say while the bill is still in the mail.

The better instinct, the one the OS vendors already adopted, is to stop asking “how full is the bar” and start asking “is this memory reclaimable, and what does reclaiming it cost.” For the page cache, the answer is “instantly, for free,” and you should relax. For Chrome’s thirty resident renderer heaps, the answer is “not for free, and you’ll feel it under pressure,” and the right response is Memory Saver, more RAM, or fewer tabs. Not a slogan.

Overall, Chrome isn’t the villain here. It’s spending RAM on isolation you want, accounting for it more honestly than your task manager does, and actively handing pages back. The villain is the one-liner that tells you none of that costs anything. It costs something. It always did. You just don’t get the invoice until the room is full.

References

Footnotes

  1. Help! Linux ate my RAM!: the canonical explainer for the page-cache origin of “unused RAM is wasted RAM.”

  2. Concepts overview (The Linux Kernel documentation): anonymous vs file-backed memory, page cache, and reclaim. 2 3 4

  3. Why is MemAvailable sometimes less than MemFree? (Oracle Linux blog): MemAvailable counts reclaimable cache and slab that MemFree does not.

  4. View memory usage in Activity Monitor on Mac (Apple Support): Memory Pressure (green/yellow/red), Cached Files, and Compressed memory. 2

  5. What they don’t tell you about demand paging in school (offlinemark): mmap returns immediately; a physical page is assigned only on first touch. 2

  6. Overcommit Accounting (The Linux Kernel documentation): the three vm.overcommit_memory modes and the commit-limit heuristic.

  7. Linux Memory Overcommitment and the OOM Killer (Baeldung): the OOM killer as the backstop when overcommitted allocations are finally touched. 2

  8. Reserving and Committing Memory (Win32, Microsoft Learn): the reserve-vs-commit model and committed memory backed by RAM or the pagefile.

  9. Introduction to page files (Microsoft Learn): “the system commit memory limit is the sum of physical memory and all page files combined,” and the system commit charge.

  10. Page State (Win32, Microsoft Learn): a committed page is charged up front, but “the system initializes and loads each committed page into physical memory only during the first attempt to read or write to that page.”

  11. Working Set (Win32, Microsoft Learn): the working set, working-set trimming under pressure, and hard page faults that read from the backing store.

  12. Process Model and Site Isolation (The Chromium Project): multi-process rationale, “memory overhead for each process,” and Spectre/Meltdown as the reason “it is no longer safe to render documents from different web sites in the same process.” 2 3

  13. Key Concepts in Chrome Memory (The Chromium Project): private vs shared pages, the shared-memory double-counting problem, and PSS being additive across processes. 2

  14. PartitionAlloc Design (The Chromium Project): returns physical memory to the OS while keeping the address-space reservation, and PurgeMemory() under low-memory pressure. 2

  15. Personalize Chrome performance: Memory Saver (Google Chrome Help): Memory Saver deactivates inactive tabs and reloads on return, with Moderate/Balanced/Maximum modes.

  16. New Chrome features to save battery and make browsing smoother (Google, The Keyword): Google’s Memory Saver announcement, claiming up to 40% less memory and up to 10GB freed.

  17. Chrome now shows each active tab’s memory usage (Addy Osmani, Google Chrome team): per-tab memory on hover and Memory Saver context.