Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Volumes, Containers, and Snapshots

APFS introduces a new storage hierarchy that differs fundamentally from traditional partitioning. Understanding containers, volumes, and snapshots is essential for effective storage management on modern macOS.

The APFS Storage Hierarchy

Physical Disk
    │
    └── Partition (APFS Container)
            │
            ├── Volume A ─── Snapshot 1
            │                Snapshot 2
            ├── Volume B
            └── Volume C

Unlike traditional partitioning where each partition has a fixed size, APFS volumes share space within a container dynamically.

Understanding Containers

What Is a Container?

An APFS container is:

  • Equivalent to a partition in terms of disk allocation
  • A pool of storage that multiple volumes share
  • The unit of encryption (container-level encryption wraps all volumes)
# View containers
$ diskutil apfs list
APFS Container (1 found)
|
+-- Container disk3 494.4 GB
    ====================================================
    APFS Container Reference:     disk3
    Size (Capacity Ceiling):      494384795648 B (494.4 GB)
    Capacity In Use By Volumes:   277848256512 B (277.8 GB) (56.2%)
    Capacity Not Allocated:       216536539136 B (216.5 GB) (43.8%)
    |
    +-< Physical Store disk0s2 494.4 GB

Container vs Partition

Traditional PartitionAPFS Container
Fixed sizeFixed size
One filesystemMultiple volumes
Resizing requires unmountVolumes resize dynamically
Independent of other partitionsVolumes share space

Multiple Physical Stores

A container can span multiple physical devices (like Fusion Drive):

# Fusion Drive example
+-< Physical Store disk0s2 (SSD) 128.0 GB
+-< Physical Store disk1s2 (HDD) 1.0 TB

This allows APFS to move data between fast and slow storage automatically.

Working with Volumes

Volume Roles

APFS assigns roles that define volume behavior:

RolePurposeCharacteristics
SystemBoot OSRead-only, sealed
DataUser dataRead-write
VMSwap spaceNot persistent
PrebootBoot helpersSmall, specific files
RecoveryRecovery OSHidden, bootable
# View volume roles
$ diskutil apfs list | grep "Role:"
    APFS Volume Disk (Role):   disk3s1 (System)
    APFS Volume Disk (Role):   disk3s5 (Data)
    APFS Volume Disk (Role):   disk3s6 (VM)

The System-Data Volume Pair

Modern macOS uses a “firmlinked” pair:

System Volume (read-only)     Data Volume (read-write)
/System                       /Users
/Library (system)             /Library (user)
/bin, /sbin, /usr            /Applications

Firmlinks make these appear as a single filesystem:

# These paths are on different volumes but appear unified
$ ls /
Applications  Library  System  Users  ...

# Check which volume a path is on
$ df /Users
Filesystem      512-blocks      Used Available Capacity  Mounted on
/dev/disk3s5   966871088 532846072 422952016    56%    /System/Volumes/Data

$ df /System
Filesystem     512-blocks     Used Available Capacity  Mounted on
/dev/disk3s1   966871088 19782344 422952016     5%    /

Creating Volumes

# Add a standard volume
$ sudo diskutil apfs addVolume disk3 APFS "DataVolume"
Exporting new APFS Volume "DataVolume" from APFS Container Reference disk3
Started APFS operation on disk3
Preparing to add APFS Volume to APFS Container disk3
Creating APFS Volume
...
Mounting APFS Volume
APFS Volume created and mounted at /Volumes/DataVolume
Finished APFS operation on disk3

# Add case-sensitive volume
$ sudo diskutil apfs addVolume disk3 "Case-sensitive APFS" "CaseSensitive"

# Add encrypted volume
$ sudo diskutil apfs addVolume disk3 APFS "Encrypted" -passphrase
Enter new passphrase:
Re-enter new passphrase:
...

# Add volume with quota (space limit)
$ sudo diskutil apfs addVolume disk3 APFS "Limited" -quota 10g

# Add volume with reserve (guaranteed minimum space)
$ sudo diskutil apfs addVolume disk3 APFS "Reserved" -reserve 5g

Volume Quotas and Reserves

# Set quota on existing volume (maximum space)
$ sudo diskutil apfs setQuota disk3s7 10g

# Set reserve on existing volume (guaranteed space)
$ sudo diskutil apfs setReserve disk3s7 5g

# Remove quota
$ sudo diskutil apfs setQuota disk3s7 0

# View settings
$ diskutil apfs list | grep -A10 "Volume disk3s7"
    +-> Volume disk3s7 DataVolume
        ---------------------------------------------------
        APFS Volume Disk (Role):   disk3s7 (No specific role)
        Quota:                     10.0 GB (10737418240 Bytes)
        Reserve:                   5.0 GB (5368709120 Bytes)

Deleting Volumes

# Delete a volume (space returns to container pool)
$ sudo diskutil apfs deleteVolume disk3s7
Started APFS operation on disk3s7 DataVolume
Deleting APFS Volume from APFS Container disk3
...
Finished APFS operation on disk3s7 DataVolume

Warning: This permanently destroys all data on the volume.

Renaming Volumes

# Rename a volume
$ sudo diskutil rename disk3s5 "New Name"

# Or
$ sudo diskutil apfs rename disk3s5 "New Name"

Working with Snapshots

What Are Snapshots?

Snapshots capture the state of a volume at a point in time:

  • Read-only view of the filesystem
  • Space-efficient (only stores changes)
  • Created instantly
  • Used by Time Machine and system updates

Viewing Snapshots

# List snapshots with tmutil
$ tmutil listlocalsnapshots /
Snapshots for volume group containing disk /:
com.apple.TimeMachine.2024-01-15-091234.local
com.apple.TimeMachine.2024-01-15-101234.local
com.apple.TimeMachine.2024-01-15-111234.local

# List with diskutil
$ diskutil apfs listSnapshots disk3s1
Snapshots for disk3s1 (2 found)
|
+-- 5A7C2E48-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|   Snapshot Name:        com.apple.os.update-XXXX
|   Snapshot UUID:        5A7C2E48-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|   Snapshot Sealed:      Yes
|
+-- 8B6C8F4E-XXXX-XXXX-XXXX-XXXXXXXXXXXX
    Snapshot Name:        com.apple.TimeMachine.2024-01-15-091234.local
    Snapshot UUID:        8B6C8F4E-XXXX-XXXX-XXXX-XXXXXXXXXXXX

Time Machine Local Snapshots

Time Machine creates hourly local snapshots:

# Create a local snapshot manually
$ sudo tmutil localsnapshot
Created local snapshot with date: 2024-01-15-143045

# View space used by local snapshots
$ tmutil listlocalsnapshots / | wc -l
      24

# Delete specific snapshot
$ sudo tmutil deletelocalsnapshots 2024-01-15-143045
Deleted local snapshot '2024-01-15-143045'

# Delete all local snapshots
$ sudo tmutil deletelocalsnapshots /
Deleted 24 Time Machine local snapshots

System Update Snapshots

macOS creates snapshots before system updates:

$ diskutil apfs listSnapshots disk3s1 | grep "update"
    Snapshot Name:        com.apple.os.update-XXXX

These allow rollback if an update causes problems.

Mounting Snapshots

# Mount a snapshot read-only
$ sudo mkdir /tmp/snapshot_mount
$ sudo mount_apfs -s com.apple.TimeMachine.2024-01-15-091234.local /dev/disk3s5 /tmp/snapshot_mount

# Browse the snapshot
$ ls /tmp/snapshot_mount

# Unmount
$ sudo umount /tmp/snapshot_mount

Snapshot Space Management

Snapshots don’t immediately use space, but they prevent space reclamation:

# View purgeable space (includes snapshot data)
$ diskutil apfs list | grep -A5 "Container disk3"
    Size (Capacity Ceiling):      494384795648 B (494.4 GB)
    Capacity In Use By Volumes:   277848256512 B (277.8 GB) (56.2%)
    Capacity Not Allocated:       216536539136 B (216.5 GB) (43.8%)

# When deleting files, space may not free until snapshots are removed

Deleting Snapshots

# Delete by name
$ sudo diskutil apfs deleteSnapshot disk3s5 -name "com.apple.TimeMachine.2024-01-15-091234.local"

# Delete by UUID
$ sudo diskutil apfs deleteSnapshot disk3s5 -uuid 8B6C8F4E-XXXX-XXXX-XXXX-XXXXXXXXXXXX

# Delete all Time Machine local snapshots (frees space)
$ sudo tmutil deletelocalsnapshots /

Sealed System Volumes

macOS Big Sur+ uses a “sealed” system volume:

$ diskutil apfs list | grep -A3 "Macintosh HD"
    +-> Volume disk3s1 Macintosh HD
        ---------------------------------------------------
        APFS Volume Disk (Role):   disk3s1 (System)
        Snapshot Sealed:           Yes

What Sealing Means

  • Cryptographic verification of system files
  • Any modification breaks the seal
  • Ensures system integrity
  • Snapshot contains known-good state

Sealed Snapshot Boot

The system actually boots from a sealed snapshot:

# Current boot is a snapshot
$ mount | grep "disk3s1"
/dev/disk3s1s1 on / (apfs, sealed, local, read-only, journaled)
#            ^^ Note the 's1' suffix indicating snapshot

Container Operations

Resizing Containers

# Shrink container to specific size
$ sudo diskutil apfs resizeContainer disk3 400GB

# Expand container to fill available space
$ sudo diskutil apfs resizeContainer disk3 0

Creating New Containers

# On a new disk or partition
$ sudo diskutil apfs createContainer disk2s2
Started APFS operation on disk2s2
Creating new APFS Container
...

Deleting Containers

# Delete container (destroys all volumes!)
$ sudo diskutil apfs deleteContainer disk3

Warning: This destroys all data in the container.

Practical Scenarios

Create a Development Volume

# Case-sensitive volume for cross-platform development
$ sudo diskutil apfs addVolume disk3 "Case-sensitive APFS" "Development" -quota 100g

# Will mount at /Volumes/Development
$ cd /Volumes/Development
$ git clone git@github.com:user/project.git

Create an Encrypted Work Volume

# Encrypted volume for sensitive data
$ sudo diskutil apfs addVolume disk3 APFS "WorkSecure" -passphrase

# Lock/unlock manually
$ diskutil apfs lockVolume disk3s7
$ diskutil apfs unlockVolume disk3s7

Recover Space from Snapshots

# Check space
$ df -h /
Filesystem       Size   Used  Avail Capacity  Mounted on
/dev/disk3s1s1  460Gi  256Gi  180Gi    59%    /

# Delete unnecessary snapshots
$ sudo tmutil deletelocalsnapshots /
$ sudo tmutil deletelocalsnapshots /System/Volumes/Data

# Verify space recovered
$ df -h /

Browse Past File Versions

# Find available snapshots
$ tmutil listlocalsnapshots /System/Volumes/Data

# Mount a snapshot
$ sudo mkdir /tmp/old_data
$ sudo mount_apfs -s com.apple.TimeMachine.2024-01-14-091234.local /dev/disk3s5 /tmp/old_data

# Browse old versions
$ ls /tmp/old_data/Users/david/Documents/

# Copy needed files
$ cp /tmp/old_data/Users/david/Documents/important.doc ~/Desktop/

# Unmount
$ sudo umount /tmp/old_data

Summary

APFS storage hierarchy:

ConceptDescriptionKey Commands
ContainerPool of storagediskutil apfs list, createContainer, deleteContainer
VolumeFilesystem within containeraddVolume, deleteVolume, setQuota
SnapshotPoint-in-time capturelistSnapshots, deleteSnapshot, tmutil
RoleVolume purpose (System, Data, VM)View with diskutil apfs list

Key advantages of APFS:

  • Space sharing: No need to pre-size volumes
  • Instant snapshots: Capture state without copying
  • Fast clones: Duplicate files without using space
  • Encryption: Built into the filesystem

Understanding this hierarchy helps you manage storage effectively, recover from issues, and take advantage of features that traditional Unix filesystems don’t offer.