macOS disk full: hundreds of gigabytes can hide in an APFS snapshot
Table of Contents
No matching heading
My Mac was down to 168 MB of free space, and nothing I deleted gave any of it back. The space was held by an APFS snapshot left behind by a macOS update. In my case it was 112 GB; depending on what you deleted since the update, it can be hundreds of gigabytes.
Symptom
du on the Data volume adds up to about 105 GB of files. diskutil reports 216.8 GB used on the same volume. That is 112 GB nobody can see. Emptying the Trash changes nothing.
The two tools answer different questions. du sums the files that exist right now. diskutil reports what the APFS container really occupies, snapshots included. When they disagree by that much, a snapshot is the usual suspect.
Cause
macOS creates APFS snapshots during some updates, to allow a rollback. One of them, com.apple.os.update-..., was still there on /System/Volumes/Data and marked Purgeable: No, so the system would never clean it up on its own. The files I had deleted since were gone from the current state of the volume, but their blocks were still referenced by the snapshot, so APFS kept them.
Two other leads checked and dismissed: deleted files still held open by a process (lsof +L1, nothing significant) and the Synology Active Backup reserved volume (2.3 GB, not enough to explain the gap).
Solution
List the snapshots on the Data volume:
diskutil apfs listSnapshots /System/Volumes/Data
Snapshot for disk3s5 (1 found)
|
+-- F333B239-21EC-4E4B-A11C-A7DA33EA074A
Name: com.apple.os.update-5514FF97DEE9C60C7FBF462B06A418D5FC4A882D5AF41D2BAF0A1419FB9B9F86
XID: 9069804
Purgeable: No
NOTE: This snapshot limits the minimum size of APFS Container disk3
Delete it by UUID (the value after +--, easier to handle than the name):
sudo diskutil apfs deleteSnapshot /System/Volumes/Data -uuid F333B239-21EC-4E4B-A11C-A7DA33EA074A
Result: the Data volume went from 216.8 GB to 183.5 GB used, and free space from 168 MB to 33.4 GB, without deleting a single file.
While you are at it, the npm cache is another place where gigabytes hide on a developer Mac:
npm cache clean --force
When du and diskutil disagree, look at the snapshots before looking for a hidden folder.