macOS, end to end: APFS containers, volumes, clones
APFS replaced HFS+ as the macOS default in 2017, and it doesn’t think in partitions. It thinks in containers and volumes: one pool of space, many volumes, all sharing it. The videos were recorded on a MacBook Pro M3 (macOS 26.6.2) with a disposable 2 GB USB disk, never the internal one; this page explains why the commands work.
The model
physical disk disk4
└── physical store disk4s1
└── container disk5 (the pool)
├── volume disk5s1 data
└── volume disk5s2 data2
The device numbers vary; check diskutil list external on your own Mac.
A container owns the space; volumes are lightweight namespaces inside it. That is why two volumes can both report 1.9 GiB free: they are not partitions with fixed borders, they are views into the same pool.
Create it
On a blank disk:
diskutil list external
sudo diskutil eraseDisk APFS data GPT /dev/disk4
diskutil list external
eraseDisk is the mkfs equivalent — it writes a GPT, an APFS container and
the first volume. The volume mounts at /Volumes/data. Then the usual proof:
echo 'hello from apfs' > /Volumes/data/hello.txt
cat /Volumes/data/hello.txt
df -h /Volumes/data
Add a volume
diskutil apfs list disk5
sudo diskutil apfs addVolume disk5 APFS data2
df -h /Volumes/data /Volumes/data2
Both volumes now show the same capacity and free space. diskutil apfs list disk5 is the map: physical store → container → volumes, with UUIDs, roles and
consumed space.
To remove one: sudo diskutil apfs deleteVolume disk5s2. The space returns to
the container immediately.
Grow and shrink
APFS resizes the container, not each volume:
sudo diskutil apfs resizeContainer disk5 1g
sudo diskutil apfs resizeContainer disk5 0
1gshrinks the container to 1 GB (the data in the volumes must fit; it’s the container’s free space that gets given back).0grows it to the maximum available.- Both run online, with the volumes mounted, and
resizeContainerruns a filesystem check internally before it resizes.
This is the opposite of XFS and ZFS: APFS grows and shrinks, and it does it at the container level.
Clones (the APFS party trick)
APFS is copy-on-write, and cp -c exposes it directly:
yes 'hello apfs' | head -n 3000000 > big.txt
cp -c big.txt big-clone.txt
cp -c does not copy the 31 MiB; it creates a clone that shares the same
blocks. It is instant, and the free space does not move. When one side is
modified, APFS copies only the changed block:
echo 'changed' >> big.txt
tail -2 big.txt # hello apfs / changed
tail -2 big-clone.txt # hello apfs / hello apfs
shasum big.txt big-clone.txt
The clone is independent after the edit, but it never paid for the initial copy. That is the same mechanism snapshots use — and a genuinely useful tool for backups, build caches and “I want a copy, but not 40 GB of one”.
A note on APFS snapshots
APFS snapshots exist, but on macOS they are Time Machine local snapshots:
tmutil localsnapshot
tmutil listlocalsnapshots /
sudo mkdir /tmp/snap
sudo mount_apfs -s com.apple.TimeMachine.2026-10-29-120000.local /System/Volumes/Data /tmp/snap
Two practical limits:
tmutil localsnapshotsnapshots the volumes included in the Time Machine backup. On a scratch external disk that is not in the backup, it creates nothing.- Mounting a snapshot read-only needs Full Disk Access for the process doing
it, and
mount_apfs -s(root), notdiskutil.
That is why the video series uses clones for the copy-on-write episode: same
mechanism, works on any APFS volume, and the result is visible in df.
Verify it
diskutil verifyVolume /Volumes/data
sudo diskutil unmount /Volumes/data
sudo diskutil unmount /Volumes/data2
sudo fsck_apfs -n /dev/disk5s1
sudo diskutil mount disk5s1
sudo diskutil mount disk5s2
verifyVolumeis the online check.fsck_apfs -nis the offline, read-only check;-yrepairs.diskutil repairVolumealso works; it unmounts the volume itself, and fails if it can’t.- To mount all volumes in the container, use
diskutil mountDisk disk5; that is the intended verb.diskutil mount disk5(withoutmountDisk) is not, and behaves unpredictably. Volume-leveldiskutil mount disk5s1also works.
APFS vs HFS+
- Space sharing (containers) instead of fixed partitions.
- Clones and snapshots — copy-on-write by design.
- Encryption per volume, native.
- Case sensitivity is a choice at format time (
APFSvsAPFSX); the default is case-insensitive. - HFS+ still exists for old media and Time Machine on some setups; for a modern Mac, APFS is the default and the right choice.
What to remember
- Container first, then volumes;
resizeContaineris the resize verb. - Volumes share free space — quotas are optional, partitions are not the model.
cp -cclones instantly and shares blocks; edit one side and only the changed blocks diverge.- Snapshots are Time Machine’s domain; clones are the everyday CoW tool.
verifyVolumeonline,fsck_apfs -noffline.
Part of Filesystems, end to end.