← All incidents

majorinfra-failureverifiedfirsthand

Time Machine sat at 66.1% for 21 hours; the culprit was three chained USB 2.0 hubs

A Time Machine backup showed "66.1%" and did not move for 21 hours. Real progress was 84 GB out of 884 GB, or 9.5%.

Observed
Severity score
6/10
Blast radius
uptime, data
Tags
#time-machine#macos#usb#backup#diagnosis

Cause

The external drive sat in a docking station at the end of three chained USB 2.0 hubs, so the link ran at 480 Mb/s. USB 2.0 handles one command per round trip, and with Time Machine writing huge numbers of small files the round trips themselves became the bottleneck, leaving close() stuck on the HFS+ destination.

Consequence

Backups were effectively down for most of a day. tmutil stopbackup could not stop the run, and a reboot was the only way out (it ended in a forced power-off, but the HFS+ journal prevented any real damage).

Fix

Remove the hubs, connect the drive directly to the Mac (5 Gb/s), and move the destination to a dedicated APFS volume. Throughput went from 5.6 MB/s to 79.9 MB/s and IOPS from 29 to 464. When an external drive is slow, check the actual link speed with system_profiler SPUSBDataType first.

What happened

On August 23, 2026, a Time Machine backup froze at “66.1%” and stayed there for 21 hours. On screen it looked two-thirds done. In reality it had written 84 GB of 884 GB — just 9.5%.

A backup that wasn’t moving was pretending that it was.

The chaos on the ground

The diagnosis was one trap after another.

First, the number lied. The 66.1% on screen wasn’t the Percent value from tmutil status at all; it was a display value computed as 0.1 + Percent × 0.9. The real progress only showed up after dividing the raw bytes by totalBytes.

Second, it was hard to tell stalled from merely slow. The drive was taking about 10 MB/s of writes, yet free space on the destination didn’t change for six hours. The backup was stuck rewriting blocks it had already allocated. Sampling df -k over time turned out to be the fastest way to tell.

Third, it wouldn’t stop. The cancel request from tmutil stopbackup timed out after 60 seconds, and backupd killed itself, complaining that cancellation took too long. Even then it lingered as a zombie. The only way out was a reboot.

What finally cracked it was spindump. All 927 samples were stuck in the same place: Copy Engine Writer → close() → HFS.kext → IOUSBMassStorageDriver. fs_usage showed every 128 KB write taking exactly 0.2 seconds — 640 KB/s. At that point it looked like close() hanging on an HFS+ destination.

Root cause

The real cause surfaced the next day. The external drive sat in an HDD docking station at the end of a USB 3.0 bus followed by three chained USB 2.0 hubs. The actual link was 480 Mb/s. The dock itself supported USB 3.0, and the volume name even said “USB 3.0” — but that was just a label with no bearing on the real link speed.

USB 2.0 mass storage processes one command per round trip. With Time Machine pushing enormous numbers of small files, the round trips ran out long before the bandwidth did. The 640 KB/s figure was exactly what synchronous flushes over USB 2.0 look like. Two hours of logs showed zero I/O errors; the drive itself was fine.

The fix

With the hubs removed and the drive plugged straight into the Mac, the link came up at 5 Gb/s. Throughput went from 5.6 MB/s to 79.9 MB/s, disk IOPS from 29 to 464, and files processed from 2,800 to 13,905 per minute. The 16x jump in IOPS mattered more than the bandwidth.

The destination also moved from HFS+ to a dedicated APFS volume. The first full backup completed 471.04 GB in 2 hours 27 minutes, averaging 53.4 MB/s.

One lesson: when an external drive is slow, suspect the cable path before you buy a new drive. Start with system_profiler SPUSBDataType and check that the link speed says Gb/s.

Sources

  • Firsthand account from the site operator. There is no public write-up to link to.