Copy-on-write, usually shortened to COW, is a memory-saving technique built around a simple idea: do not copy data until somebody actually changes it. Linux uses this idea heavily when one process creates another with fork().
If a process using several gigabytes of memory calls fork(), Linux does not normally duplicate every byte of that physical RAM immediately. Instead, the parent and child can temporarily point at the same physical pages while the kernel uses virtual memory and page-table permissions to keep the two processes logically separate.
The Big Idea: Share First, Copy Later
Imagine a parent process has 1 GB of private memory and calls fork(). The child needs to begin with what looks like the same address space. A naive implementation could allocate another 1 GB and copy everything immediately.
Copy-on-write avoids that eager copy. Parent and child initially reference the same physical memory pages. Their page-table entries are arranged so ordinary reads can continue, but a later write to a shared COW page triggers kernel work before the modification is allowed to become private to that process.
The Linux fork(2) manual page explains that Linux implements fork() with copy-on-write pages, so the initial cost is dominated more by duplicating page tables and process structures than by copying all of the parent’s physical memory.
A Write Turns Into A Page Fault
The interesting moment happens when the parent or child tries to modify a page that is still shared under copy-on-write rules. The page is not currently writable in the way that process expects, so the CPU’s memory-management hardware raises a page fault.
The kernel examines the fault and recognizes that this is not necessarily a programming error. It can allocate a new physical page, copy the old page’s contents into it, update the writing process’s page table to point at the private copy, make that mapping writable, and then resume the instruction. Only the page that was changed needs to be copied.
Page Tables Make The Trick Possible
Each process has its own virtual address space, but virtual addresses are translated to physical memory through page tables. Two different processes can therefore have virtual pages that point to the same physical frame without sharing an identical page-table structure.
The official Linux kernel documentation on page tables and page faults explicitly lists copy-on-write as a normal reason the MMU can trigger a fault. The kernel’s fault handler then decides whether the access should be satisfied, copied, rejected, or handled in some other way.
fork() Is Fast Because Most Programs Do Not Need An Immediate Full Copy
A common Unix pattern is fork() followed quickly by exec(). The child exists briefly with the parent’s inherited address-space view, then exec() replaces that address space with a new program. Copying every private memory page before that replacement would often be wasted work.
Copy-on-write therefore makes the normal fork-and-exec workflow much more practical. Pages that nobody modifies can remain shared until the old relationship disappears.
COW Does Not Mean fork() Is Free
Linux still has work to do when a process forks. It must create a new process, duplicate or establish references to process metadata, build the child’s page-table view, and manage references to files and other resources. A very large address space can therefore make fork() noticeably more expensive even when physical pages are not eagerly copied.
Writes after the fork also cost something. A workload that rapidly modifies most of its private memory can trigger many COW faults, allocations, and page copies. Copy-on-write is efficient when sharing lasts long enough to avoid unnecessary copying; it does not eliminate the cost of eventually diverging data.
MAP_PRIVATE Uses The Same General Idea
Copy-on-write also appears with private memory-mapped files. A mapping created with MAP_PRIVATE can initially reflect file-backed pages, but changes made through that private mapping are not written back as modifications to the original file.
When a process writes to a privately mapped page, Linux can give that process a private changed copy while preserving the original file-backed contents for other users of the file. That is the same broad COW philosophy: share an existing representation until mutation requires separation.
Why Memory Numbers Can Be Confusing After fork()
After a fork, both processes may show substantial resident memory even though some of those physical pages are shared. Simply adding two processes’ RSS values can therefore overstate how much unique physical RAM the pair consumes.
Linux exposes more detailed accounting in /proc/<PID>/smaps. Metrics such as proportional set size can help distribute the cost of shared pages across the processes using them, while private dirty pages reveal memory that has diverged from shared backing.
grep -E 'Rss|Pss|Private|Shared' /proc/<PID>/smaps_rollup
Copy-on-Write Also Appears In Storage
The term copy-on-write is not limited to process memory. Filesystems and storage systems can apply the same principle at a different layer: instead of overwriting an existing block in place, they can preserve the old block and write changed data somewhere else.
That design enables efficient snapshots and clones because unchanged blocks can remain shared. It is conceptually similar to memory COW but technically distinct: one mechanism works with virtual-memory pages and process address spaces, while another works with persistent storage blocks, metadata, and filesystem consistency.
Copy-on-Write Has Security History Too
Because COW sits directly in the virtual-memory and page-fault path, bugs in its implementation can have serious consequences. The famous “Dirty COW” vulnerability exploited a race involving private read-only memory mappings and copy-on-write handling, demonstrating that a performance optimization can also become part of the system’s security boundary.
The lesson is broader than that one vulnerability: memory ownership, permissions, reference counting, and page-fault behavior all have to remain correct even when many threads or processes interact with the same underlying data.
COW Works With The Page Cache, But They Are Not The Same Thing
The Linux page cache keeps file-backed data in RAM to reduce storage I/O. Copy-on-write is a policy for delaying duplication until a write requires a separate copy. The mechanisms can interact, especially with private file mappings, but they solve different problems.
A useful rule is: the page cache answers “can this file data stay in RAM for reuse?” while copy-on-write answers “can these users keep sharing the same underlying data until one changes it?”

A Small Mental Example
Suppose a parent has four private memory pages: A, B, C, and D. After fork(), parent and child can initially reference the same physical A, B, C, and D pages. If the child modifies only page C, Linux can create a new C page for the child while A, B, and D remain shared.
That is why COW scales better than immediately duplicating the entire address space when only a small portion will change. The amount of extra physical memory grows with the pages that actually diverge, not automatically with the full virtual size of the process.
The Short Version
Copy-on-write lets Linux delay expensive copying. After fork(), parent and child can share physical pages. A write to a shared COW page triggers a page fault, Linux creates a private copy for the writer, updates the page tables, and execution continues.
The sentence to remember is: share memory while it stays identical; copy only the pages that actually change.
Editor’s Note
This evergreen explains the practical Linux copy-on-write model. Exact fault paths, page-table behavior, accounting, huge-page interactions, and implementation details vary across kernel versions and architectures.
BitcoinVersus.Tech is independently maintained. Support options on the site help fund additional technical research, verification, and open educational publishing.
BitcoinVersus.tech is not a financial advisor. Content is provided for informational purposes.

Leave a Reply