With my new home server, I’ve made some changes (improvements, hopefully) to my backup system.
To back up my Mac, I’ve always started with Time Machine. It has good operating system support, and it can do frequent incremental backups, even when you aren’t connected to the backup disk. It isn’t great for long-term backups though, because every year or so, it gets corrupted and you have to start over from scratch, losing old versions of your files. It seems to be worse when backing up over the network, so I only use Time Machine to a directly connected hard drive.
I’ve used Backblaze, which does internet backups. You can also configure it to keep old versions of your files, although beyond a certain point you have to pay per gigabyte. Backblaze has been pretty reliable, although if you have multiple devices, the per-month price starts to add up.
I’ve used Arq, backing up either to a network drive or to Backblaze B2. This seems to work pretty well. The concept is very similar to Backblaze except that it is more flexible on where you put the data. I don’t use this on my main machine any more, but my kids do on their laptops because it is good about sending data over the internet to my home server (using RustFS to run an S3-compatible server).
All of these backup systems do somewhat complex things to allow you to store multiple versions of files, which is a very important feature for a backup system, in case you accidentally delete or change something and you want to get it back.
A different strategy is to make the backup client dumb but the storage system smart. Since I’m using ZFS for my home server, I can do snapshotting and versioning there. Not only does this simplify things for the client, it gives me more flexibility, for example, to keep many snapshots on the large home server but only send one or two versions to the smaller offsite backup drives.
SuperDuper focuses on exact copies of the entire filesystem. It typically uses an APFS-formatted external drive, but it also has support for network shares. As of MacOS 26, these network backups use Apple’s new sparse image (ASIF) format. On the server side, this looks like a giant file big enough to store all of your data.
After each backup, I have SuperDuper trigger a ZFS snapshot, which allows me to travel back in time to see a day’s backup even after future SuperDuper “Smart Updates” have changed the live version of the sparse image on the server. And ZFS doesn’t have to store an entire copy of each sparse image, just the parts that have changed from one instance to the next.
You don’t get a fancy browser that can see all former versions of a file, the way that Time Machine does. From MacOS’ point of view, you have an entirely separate sparse image per backup, just stored in a way that they don’t have to duplicate unchanged data. You do get all of the Apple-native file features, since the backup targets are full APFS filesystems.
Carbon Copy Cloner is more flexible when making copies to an attached hard drive, including using APFS snapshots to store multiple versions of a file, the way that Time Machine does. But it is much more limited when using network storage: it copies individual files and doesn’t support versioning or other APFS features.
I find it useful, especially when combined with ZFS snapshots, because it makes it easy to see a file’s change history over time. It is more transparent than sparse images, even if it is less faithful.
I also want an offsite backup, to make sure that I’m safe in case both my Mac and home server are taken out at the same time. For this, I use an old hard drive big enough to store just a few of the latest snapshots, and a Perl script called syncoid (part of the snapshot manager sanoid).
The backup script looks essentially like this:
syncoid --identifier=offsite --compress=none \
--recursive --sendoptions=w \
--delete-target-snapshots \
main offsite/main
The first time this is run, it creates a snapshot of the ‘main’ dataset and then copies that snapshot to the offsite dataset, which is stored on the external drive. The identifier is used as part of the snapshot name, in case you want to set up multiple backup targets.
On subsequent runs, it creates a new snapshot, and then sends everything that has changed since the previous syncoid snapshot (including any snapshots that you make by other means) to the backup target. Then it deletes the previous snapshot.
Compression is turned off because I am copying to a USB hard drive, not over the network (although syncoid will work over SSH as well). The ‘w’ option sends raw encrypted datasets, which isn’t strictly necessary since you can always configure the target to re-encrypt everything. Deleting the target snapshots means that if you delete a snapshot on the source, it gets deleted from the target.
I keep two identical backups, one connected that is receiving daily syncs, and the other at my office. Every 2-3 weeks I swap them, so that the office copy isn’t more than a month out of date.