Time Machine on APFS: snapshots, network backups, and rollback
How Time Machine uses APFS snapshots for local backups, the per-hour/per-day/per-week retention policy, and what rollback actually does to your filesystem.
Time Machine on a modern Mac is two systems working together: APFS snapshots for the local hourly history, and an external destination (USB drive, NAS, AirPort Time Capsule, or another Mac) for the off-device backup. Both rely on the same APFS snapshot machinery underneath.
This article walks how the pieces fit, what's actually copied when, and what happens when you rollback.
The local snapshots — the always-on safety net
Even without an external destination configured, Time Machine takes local snapshots on your Mac's startup volume:
- Hourly, when on AC power and idle for a few minutes.
- Kept for 24 hours, then pruned.
These are pure APFS snapshots — the kernel-level snapshot mechanism. Creation is O(1); they cost essentially nothing in storage at creation, growing only as the live volume diverges from the snapshot.
You can see them with:
tmutil listlocalsnapshots /
# com.apple.TimeMachine.2026-06-01-103214.local
# com.apple.TimeMachine.2026-06-01-093214.local
# ...
And create one manually:
tmutil snapshot
This is the same machinery fs_snapshot_create(2) exposes — see the APFS clones article for the syscall layer.
The destination backups — full + differential
When you configure a Time Machine destination, the backup model gets richer:
- First backup: full copy of every file from the source to the destination, plus the source's APFS snapshot tree.
- Subsequent backups: differential — copies blocks that changed since the previous snapshot.
The destination is itself an APFS volume (since macOS 11; older versions used HFS+ with directory hardlinks). The backup process:
- Take a fresh APFS snapshot on the source volume.
- Compute the diff against the last snapshot the destination knows about.
- Stream the changed blocks to the destination's corresponding snapshot tree, allocating fresh blocks on the destination.
- Update the destination's snapshot index to record the new backup.
- Optionally delete now-redundant snapshots on the source.
Because both sides are APFS with snapshots, the diff is computed at the extent level — the source knows which extents changed since the previous snapshot (the b-tree XID lookup tells it), and it streams just those.
Retention policy
Time Machine's retention has three bands:
| Age | Kept |
|---|---|
| Last 24 hours | hourly |
| Last month | daily |
| Older | weekly |
When a backup completes, Time Machine prunes snapshots that no longer fit any band — e.g., the third hourly from yesterday is dropped because there's already a daily covering that day.
Pruning is just deleting the snapshot, which the kernel handles via fs_snapshot_delete. Blocks that the snapshot was pinning become eligible for garbage collection by the APFS allocator.
Network backups — over SMB to a NAS or Time Capsule
For network destinations:
- The destination exposes an SMB share.
- Time Machine mounts the share.
- Inside the share, Time Machine creates a sparsebundle disk image (a directory of band files that together represent an APFS volume).
- Backups go into the sparsebundle — which the local kernel mounts as an APFS volume.
This is why network Time Machine is slower than direct-USB: every block goes through SMB framing + the sparsebundle format + the actual network round-trip. Direct-attached USB or Thunderbolt is dramatically faster.
Rollback — restoring from a snapshot
When you "Enter Time Machine" and restore a previous version of a file:
- The Time Machine UI mounts the relevant snapshot read-only at a synthetic path (under
/Volumes/.timemachine/). - You browse the snapshot's filesystem as if it were a separate volume.
- Selecting a file to restore: the system copies that file from the snapshot mount to the live volume's location.
It's a regular file copy at the user level, exploiting the snapshot's read-only view of the past. The snapshot itself isn't modified; the live volume gains a fresh copy.
For a system-wide rollback (restore everything to a previous snapshot), the mechanism is different:
- Boot into recoveryOS.
- recoveryOS knows how to do a
fs_snapshot_reverton the boot volume. - The live volume's root b-tree gets replaced with the snapshot's root.
- All changes since the snapshot are lost (the blocks become garbage-collectable).
System-wide revert is exposed via tmutil restore and friends. It's much faster than a file-by-file restore — O(1) at the b-tree level.
What happens during a backup, on the kernel side
The user-space backup daemon (backupd) drives the show. Kernel side:
fs_snapshot_create—backupdcreates a fresh snapshot. Kernel allocates a new snapshot tree, marks all current blocks as pinned. ~milliseconds, regardless of volume size.fs_snapshot_diff(private SPI) —backupdasks the kernel which extents changed since the previous snapshot. The kernel walks the b-tree comparing XIDs.- File reads from the snapshot —
backupdreads from the snapshot mount; the kernel reads the right block versions via the snapshot's b-tree. - Block-level streaming to destination —
backupdwrites to the destination, which goes through its own APFS volume's normal write path. fs_snapshot_delete— old snapshots no longer needed get deleted; the kernel marks their pinned blocks as eligible for reclamation.
What surprises newcomers
- Time Machine works even without a destination. Local hourly snapshots are always on for the boot volume.
- A 1-hour backup of 1 TB takes seconds. Snapshot creation is O(1); the differential is small.
- A snapshot doesn't "save space" — it pins blocks. Snapshots full of unique data consume the data's space. Snapshots of mostly-unchanged data consume almost nothing.
- Network Time Machine performance is constrained by the sparsebundle, not just the network. The disk-image-in-a-share architecture is the bottleneck.
What to read next
For the snapshot syscalls and the APFS COW machinery this builds on:
apple-oss-distributions/xnubsd/vfs/vfs_syscalls.cWhere the snapshot syscalls land in the BSD layer before dispatching into APFS.View on GitHub(line —)And the APFS clones and snapshots article — the syscall-level layer Time Machine builds on top of.