Why Time Machine backups can be interminably slow

My interest in poor Time Machine performance when backing up Xcode was rekindled with a series of insightful tweets by Saagar Jha @_saagarjha, who has discovered how to decompress Xcode downloads more efficiently.

If you obtain and maintain Xcode through the App Store, this doesn’t apply; for those who get their copies direct from Apple, this is delivered as a compressed .xip which is notoriously slow to decompress. As Xcode is so vast, with more than half a million files and over 30 GB in fully decompressed size, delivery and installation is never going to be simple.

Saagar Jha reports that decompression using the command tool xip saves significant time over using Archive Utility, which is the default. He attributes much of this saving from time spent in Sandbox evaluation, making it kernel-bound.

Revisiting what happens when Time Machine’s backupd is chugging its way through backing Xcode up to an APFS volume, there are no clues as to what it’s spending its time doing, other than reports every five minutes on backupd progress, such as the figures
72.32 MB/s, avg: 17.91 MB/s, 323.87 items/s, avg: 367.99 items/s

At those averages, Xcode would take around 30 minutes to back up on the basis of size or file count, and that’s what it will achieve on a good day. That’s far slower than decompression-installation, although when backing up to APFS, all that should be happening is that the whole of Xcode is copied from the source to backup storage.

One well-known control is the throttling of I/O, which is deliberately applied to tasks such as Time Machine backups, according to the documentation in the man page for setiopolicy_np(). backupd is set to run at IOPOL_THROTTLE, which means that all its I/O including writing to disks “will be throttled to avoid impacting performance of higher priority I/Os.”

There’s another part to this, at least in M1 Macs, in that backupd threads must also be given sufficient % CPU to be able to take advantage of any release of that throttle. Having demonstrated how user threads can make best use of the Efficiency (E) cores in the M1 Pro, my next step was to inspect what happens during a backup using powermetrics and the CPU History window. Here I was surprised to see that, while backupd accounted for around 90% active residency on each of the two E cores during a backup, those cores were largely running at 972-1332 MHz, around half their maximum frequency.

By default, then, Time Machine backups are run exclusively on the E cores, at economy mode to minimise power consumption, with an I/O throttle preventing them from accessing storage at normal speed. These limit it to backing up no more than 300-400 items/s, which in turn means that folders containing very large numbers of items will take a long time to back up.

Sadly, Apple doesn’t provide any options for the user to accelerate a backup, nor does backupd change its settings when it knows that there are a great many items to be copied. What options does the user have?

Removing the IOPOL_THROTTLE setting can be performed at the command line, or using St. Clair Software’s App Tamer, which can not only be used to slow or stop apps, but has a control to do this for Time Machine. The snag is that this is too blunt an instrument, as it removes all such I/O throttling, not just for backupd.

It was a comment on this blog by ConfuSomu which drew my attention to the command tool taskpolicy, which not only reschedules user processes between cores, but can also run a task with IOPOL_THROTTLE removed. Sadly, that doesn’t prove suitable here, as it can only modify IOPOL_THROTTLE on tasks which it runs, not those already running like backupd, and it can’t reschedule low QoS system processes either.

The latter is a great shame, as the command
taskpolicy -B -p 567
changes the QoS of the process with a PID of 567 so that it can use both types of core. As backupd is run by root, this has to be used with sudo‘s elevated privileges, and doesn’t change the use of cores by backupd in the slightest. It appears that taskpolicy can’t override core use by any thread set to run at the lowest QoS of 9. They appear confined to the E cores no matter what you try with taskpolicy, which can only be used to move threads with the three higher QoS levels set.

At the end of all this, I conclude that, whatever we might try, Time Machine backups are set to take as long as they take, copying no more than around 400 items/s. Any attempt by the user to alter that has unwanted global effects (IOPOL_THROTTLE) or just doesn’t work (taskpolicy). Only Apple can change that, perhaps when it realises that blisteringly fast M1 Macs deserve faster backups too. I’m sure that Carbon Copy Cloner and other backup utilities can perform better.