How Does a 100 GB Game Run on 16 GB of RAM?
You just downloaded a 120 GB open-world RPG. Your machine has 16 GB of RAM. You press Play — and it works. No crash. No warning. Just the game running.
That is not luck. That is your operating system being incredibly clever.
The Mental Model
Think of RAM as a chef's counter — a small, fast workspace. The 120 GB game sitting on your SSD is the grocery warehouse out back. The chef never drags the entire warehouse onto the counter. She brings only what she needs right now, and swaps ingredients as the dish changes.
Your OS is that chef. Everything below is just the engineering that makes her fast.
Pages and Frames — Cutting Memory Into Slices
The OS does not manage memory one byte at a time — that would be impossibly slow. Instead, it divides everything into neat, fixed-size chunks called pages.
- A page is a 4 KB chunk of virtual memory — the address space your program sees.
- A frame is a 4 KB chunk of physical RAM — actual hardware memory.
They are the same size by design. The OS job is simply to decide: which virtual page maps to which physical frame, right now?
Why 4 KB? It is a sweet spot — small enough to avoid wasting RAM loading data you will never use, large enough that the bookkeeping stays efficient.
Think of pages as numbered tickets and frames as actual seats. Your program holds tickets. The OS assigns seats. The same seat can hold a different ticket tomorrow.
The Page Table — The Address Book
For every running process, the OS maintains a data structure called a page table. It is the address book that answers one question: "For this virtual address my program is using, where is it actually sitting in RAM?"
But storing one entry for every possible page in a 512 GB virtual address space would take gigabytes just for the bookkeeping — before a single byte of your game loads. That is impractical.
The solution is a three-level tree. Instead of one massive flat list, the page table is split into three small tables that chain together. Branches of the tree that cover memory you have never touched simply do not exist, keeping the whole structure lean.
Here is how a virtual address is split to walk that tree:
Virtual Address
┌─────────────┬───────────┬───────────┬───────────┬──────────────┐
│ unused │ L2 index │ L1 index │ L0 index │ page offset │
│ (25 bits) │ (9 bits) │ (9 bits) │ (9 bits) │ (12 bits) │
└─────────────┴─────┬─────┴─────┬─────┴─────┬─────┴──────────────┘
│ │ │
CPU register ──► L2 Table │ │
┌──────────┐ │ │
│ entry ──┼────► L1 Table │
└──────────┘ ┌──────────┐ │
│ entry ──┼─► L0 Table
└──────────┘ ┌──────────┐
│ entry ──┼──► Physical Frame
└──────────┘ + page offset
│
▼
Physical Address
Each level uses 9 bits of the virtual address to pick one of 512 entries, chaining down to the final Page Table Entry (PTE) — which holds the physical frame number and a set of permission flags.
The most important flag is V (Valid). If V = 1, the page is in RAM and the translation succeeds. If V = 0, the page is not in RAM — and the CPU raises a page fault.
Demand Paging — Load It Only When You Need It
Here is the trick that makes the whole thing work.
When your game launches, the OS does not load 120 GB into RAM. It creates the virtual address space, builds a skeleton page table with every V flag set to 0, and hands control back to the game immediately. Nothing is loaded yet.
Pages only enter RAM the moment your program actually touches them. This is called demand paging — pages are loaded on demand, not in advance.
The result? Your game starts in seconds, uses only the RAM it genuinely needs right now, and the other 100+ GB sits quietly on disk until a new area, texture, or piece of audio is actually needed.
It is like a library that only prints the pages of a book when you ask to read them, rather than printing all 800 pages the moment you walk through the door.
Page Fault — The Invisible Hand
So what actually happens when your program touches a page with V = 0?
The CPU cannot proceed on its own. It raises a page fault — a signal to the OS that says "I need this page and it is not here." The OS catches it, handles it entirely behind the scenes, and resumes your program as if nothing happened.
Program accesses a virtual address
│
▼
CPU walks the page table
│
┌────┴────┐
V = 1 V = 0
│ │
▼ ▼
Translation PAGE FAULT
succeeds │
✓ OS takes over
│
1. Find a free physical frame
2. Read the page from disk or swap
3. Update the PTE → V = 1, set frame address
4. Resume the program at the same instruction
│
▼
Translation now succeeds ✓
The program never knows a disk read just happened. From its perspective, the memory was simply there.
There are two kinds of page faults worth knowing:
| Type | What it means | Cost |
|---|---|---|
| Minor fault | Page is already in RAM but not yet mapped (e.g. a shared library another process loaded) | Tiny — just update the PTE |
| Major fault | Page must be read from disk or swap | Expensive — milliseconds of disk I/O |
Major faults are the ones you feel — that brief freeze when a new zone loads, or a stutter when the game streams in a new area. The OS is making an urgent trip to the warehouse.
When RAM Fills Up — The Eviction
Demand paging only works if there are free frames to load pages into. When RAM is full, the OS must evict an existing page to make room.
It tries to evict the page you are least likely to need soon — something you accessed a long time ago and have not touched since. This is tracked by the A (Accessed) flag in each PTE, which the CPU sets automatically on every read or write.
If the evicted page was never written to, it can simply be discarded — it can always be reloaded from disk. If it was written to (the D (Dirty) flag is set), the OS must save it to swap space on disk first, then free the frame.
RAM is full. New page needed.
│
▼
Find a cold page (A flag untouched for a while)
│
┌────┴────┐
D = 0 D = 1
(clean) (dirty)
│ │
▼ ▼
Discard Save to swap, then discard
immediately
└──────┬──────┘
▼
Load the new page into the freed frame ✓
When RAM is so overwhelmed that the OS spends more time evicting and reloading than actually running your game, everything grinds to a halt. That is called thrashing — and it is why adding more RAM to a struggling system feels like magic.
The Full Picture in One Flow
Press Play
│
▼
OS creates virtual address space
Page table built — all V = 0, nothing in RAM
│
▼
Game runs → touches new memory → page fault
OS loads that page from disk → V = 1
Game continues, none the wiser
│
▼
RAM fills up → OS evicts cold pages
Dirty pages saved to swap, clean ones dropped
│
▼
New area loads → more page faults → more loads
Old area's pages quietly evicted in the background
│
▼
Game runs smoothly — only what you need is in RAM
The other 100 GB waits patiently on disk
That is the whole illusion. Virtual addresses make your program feel like it owns everything. Pages and frames make memory manageable. Demand paging means you only pay for what you use. And page faults are the invisible hand that makes it seamless.
The next time your game stutters for a split second entering a new area, you know exactly what just happened — the chef made a trip to the warehouse.
Top comments (0)