The problem with APFS snapshots

In yesterday’s article, I showed how I was able to restore a trashed APFS volume using a snapshot. The main lesson is that, while this is superbly quick and essentially simple, only a very limited number of backup apps are currently able to make snapshots. Restoring from a snapshot is thus only normally available to those volumes which are already being backed up. This article explains why that is.

Snapshots take advantage of the way in which APFS uses its copy on write feature with changing file contents. When changed data are written out to an existing file, it’s written not to the block containing the original data, but to a different block. Not only that, but APFS only writes out as much new data as it needs to.

CoS1

Let’s say that our original document is stored in two blocks, and we make changes which affect only the contents of the second.

CoS2

Instead of APFS writing out new versions of each of those blocks, it only writes the changed block, and the new file is then composed of one new and one old block. So long as all three blocks are kept in storage, the file system can readily deliver either the original or the changed version of that file.

When a snapshot is made, a copy of the file system metadata is made, and the original storage blocks at that instant are preserved. By replacing a later set of file system metadata with the previous copy, provided the original data also remains, that volume can be returned almost instantly to the state at the time of the snapshot. In the case of MyDocument.doc in the diagrams, it would mean pointing the restored version of the file at the two original blue blocks, rather than one blue and one pink.

When you first make a snapshot, it takes up no new storage space itself, and CCC shows it as taking at zero KB. As the volume is used, and changes are made to its contents, for the snapshot to remain usable, all the old storage blocks have to be retained, as does its original metadata. The diagrams above show one document, which after its next edit requires a second storage block for the changed data. If it then undergoes more change, it may require a second storage block, having no storage in common with the original.

This is why the size occupied by a snapshot increases steadily after it is made, until ultimately it could require the same amount of storage space as if it had been a complete duplicate. If you’re working with a few GB of data on a 2 TB volume, that isn’t a problem. But if each snapshot could rise to 1 TB, and you’ve got dozens of snapshots, they could rapidly come to occupy all the free disk space, and block the file system from functioning.

Apple has come up with a portable derivative of the snapshot, the ‘delta’ or difference between snapshots, which can help reduce this problem. However, snapshots remain amazingly powerful tools with this one fatal flaw – they can readily consume all your storage.

Return for a moment to the user we want to protect from indvertently trashing the contents of an external SSD, without having to back it up. We could let them make a snapshot whenever they liked, perhaps, leaving it to them to remove old snapshots whenever they remembered. Even conscientious users would quickly find themselves running into trouble with very large old snapshots taking over their disk free space.

Users who are careful enough to keep only a minimum of recent snapshots could still lead to problems for the file system. Making a snapshot is (almost) instant enough, but removing one is much harder work. So much so that APFS has a sub-system designed to work through all the old storage blocks used by a snapshot and free them up. It’s appropriately named the Reaper.

Making snapshots is a feature which is therefore closely controlled by Apple. For a third-party developer to obtain the special entitlement to do this, they need to demonstrate that their app will not only make those snapshots – the easy part – but will maintain them automatically so that users don’t clog their storage up with old snapshots. Both Time Machine and CCC have stringent controls over how long they will keep snapshots for, and automatically remove them once they’ve expired. This explains why the command
tmutil localsnapshot
only works with volumes which are in your Time Machine backup set, and can’t be used to create arbitrary snapshots of any passing volume whenever you feel like it.

There’s no reason why snapshots can’t be used in tools which are aimed primarily at restoring volumes and their contents without making full physical backups, and for many reasons these may have a more promising future with APFS than conventional repair tools. But they will also need to perform careful housekeeping on their snapshots – and that’s the difficult part.

Further reading

Time Machine snapshots
Carbon Copy Cloner and snapshots.