Cloning a 300GB Chromium Checkout in 0.024 Seconds

โšก Tools ๐Ÿ”ง btrfs / Linux ๐Ÿ‘ค Helmut Januschka

How btrfs subvolumes turn Chromium checkout clones from an overnight job into a free operation

The Problem

A Chromium checkout is a monster: ~300GB, millions of small files, a .git directory
that has seen things. If you work on multiple things in parallel - a bisect here, an
experiment there, a risky rebase you want a safety net for - you eventually want a
second tree.

The naive options are all bad:

On btrfs there is a better way, and once set up, clones are instant and free.

btrfs supports copy-on-write file clones via reflinks. The copy shares all data
blocks with the original - only metadata is written:

cp -a --reflink=always ~/chromium ~/chromium_2

For my 304GB tree this took about 2 minutes (it is bound by inode creation, not
data), and zero additional data blocks. Disk usage barely moves. Files only
start taking real space when one side modifies them - classic copy-on-write.

That alone beats every other option. But we can do better.

Step 2: Convert the Checkout to a Subvolume

Reflink copy still walks millions of inodes. A btrfs snapshot of a subvolume is
one metadata operation - but it only works on subvolumes, and your checkout is
probably a plain directory.

The one-time conversion (no root needed):

# 1. a new empty subvolume
btrfs subvolume create ~/chromium.subvol

# 2. reflink everything into it (the ~2 minute step, no data copied)
cp -a --reflink=always ~/chromium/. ~/chromium.subvol/

# 3. swap names
mv ~/chromium ~/chromium.old
mv ~/chromium.subvol ~/chromium

# 4. once a build confirms everything works, reclaim the old tree
rm -rf ~/chromium.old   # slow; run it overnight

Two caveats for step 2: make sure no build (siso/ninja) is writing to the tree
while it copies, and verify the result before deleting the old directory. In my
case: all 104 local branches, the checked-out branch and git status came through
intact.

Note that deleting ~/chromium.old does not free 300GB - the data blocks are
shared with the new subvolume. It only frees the duplicate inode metadata. You
never had the data twice.

Step 3: Instant Clones, Forever

With ~/chromium as a subvolume, a full clone of the entire checkout is:

btrfs subvolume snapshot ~/chromium ~/chromium_2

On my machine:

real    0m0.024s

24 milliseconds. All 300GB, all branches, all build state, atomically, with no
additional disk usage. Deleting one is just as fast:

sudo btrfs subvolume delete ~/chromium_2

Compare that with rm -rf on a Chromium tree, which takes long enough that you
start it before leaving the office.

Operation Plain directory Subvolume
Clone hours (cp) / minutes (reflink) 0.024s
Delete clone ~1 hour (rm -rf) instant
Extra disk per clone 0 (reflink) - 300GB (cp) 0
Atomic no yes

Atomicity matters more than it sounds: a reflink cp walks the tree over minutes,
so a build writing concurrently gives you a torn copy. A snapshot is a single
point-in-time image.

Caveats

A few things worth knowing:

The Workflow This Unlocks

Since clones are free, they stop being precious:

The 300GB checkout stops dictating how you work. That is the whole point.

Thanks to