Skip to content

Experiment Log: Impact of Unplugging the Drive on APFS Volumes and Disk Images ​

This page is the raw record of a controlled experiment, used to answer a question that came up when choosing the backend for mount migration:

If container data is kept in an APFS volume on the external drive, versus in an APFS disk image (sparsebundle) on the external drive, and the drive is pulled out mid-write, how much does each lose?

The answer: the entire disk-image volume became unusable in both test rounds, while the APFS volume lost only its last few transactions. For the user-facing explanation, see Why the External Drive Must Be APFS.

Environment ​

ItemValue
SystemmacOS 27.0 (26A428), arm64
Test drive64 GB USB flash drive (U352), used after diskutil eraseDisk APFS APTEST GPT
APFS volumeNewly created with diskutil apfs addVolume in the test drive's APFS container, diskutil mount -mountPoint ~/appports-test/usb-apfsmnt
Disk imagehdiutil create -type SPARSEBUNDLE -fs APFS -size 20g, stored at the root of the test drive, hdiutil attach -mountpoint ~/appports-test/usb-imgmnt -nobrowse
Write workloadPython script: SQLite synchronous=FULL + WAL, inserting in a loop and committing each row individually, while also writing a 64 KB file every 50 commits; each commit writes a line committed N to a log
Unplug methodPulled the USB connector directly, without ejecting
Date2026-09-19

Round 1: Plain fsync ​

The two writer processes ran in parallel for 12 seconds, then the drive was pulled.

Last commit before unpluggingAfter plugging back in
APFS volume7177yank.db reports database disk image is malformed; sqlite3 .recover recovered 7172 rows, max(id)=7172; all 50 files present
Disk image25574hdiutil attach reported "无可装载的文件系统" (no mountable file systems); fsck_apfs reported container superblock is invalid; the band 0 file was only 3.26 MB (it should normally be 8 MB)

The image's commit count is more than three times the volume's, which shows that its writes mostly stayed in the host's page cache and never actually reached the disk.

Round 2: F_FULLFSYNC ​

The writer script added pragma fullfsync=1; pragma checkpoint_fullfsync=1, which is how SQLite on macOS truly forces writes through to the medium (most apps don't enable it). Both sides became much slower.

Last commit before unpluggingAfter plugging back in
APFS volume1906integrity_check = ok, 1905 rows, max(id)=1905
Disk image373Still could not be mounted; superblock invalid

Even with the strictest possible flushing at the application layer, the checkpoint area of the APFS file system inside the image (which lives in band 0) was still left half-written.

Round 3: ASIF (Aborted) ​

macOS 26 and later offer ASIF, a single-file sparse image format (diskutil image create blank --format ASIF). After mounting one, we wrote to it for 12 seconds (8000 commits) and decided to abort before pulling the drive: ASIF is only available on 26+, so it is meaningless for the target users (12 through 26), and, like APFS volumes, it requires the host to be APFS, so it does not solve the exFAT problem.

Performance Comparison (Before Unplugging, Same USB Flash Drive) ​

WorkloadInternal SSDAPFS volumesparsebundle (host: APFS)sparsebundle (host: exFAT image)Writing directly to exFAT
SQLite, 2000 individual commits0.07 s0.35 s0.10 s0.17 s1.69 s
2000 small 4 KB files0.08 s0.10 s0.08 s0.09 s0.76 s
256 MB sequential write + fsync0.07 s0.31 s0.37 s0.67 s0.80 s

The image's database commits were even faster than the APFS volume's, precisely because it was not really reaching the disk. The exFAT column shows that even if a database could be placed directly on exFAT, its performance would be unsuitable for workloads like chat history.

Other Observations ​

  • The image approach does not trigger the "Removable Volumes" TCC authorization: the built-in Stickies (a platform app) was silently denied on the APFS volume, but read and wrote normally on the image, with no deny of any kind in the logs.
  • The image does not give space back after files are deleted: after writing and then deleting 5 GB, the image still took up 5.6 GB and needed hdiutil compact.
  • After the unplugging, fsck_apfs reported both of the test drive's own APFS volumes as healthy; the corruption occurred only inside the image.

Conclusions ​

APFS volumeDisk image
Loss when unpluggedThe last few transactions; the database is repairableThe entire volume
External drive formatMust be APFSAny
TCC authorization promptOnce, the first timeNone
PerformanceNativeComparable (because writes don't reach the disk)

AppPorts therefore offers only the APFS volume backend. The image approach's other advantages are not enough to offset "unplug once and the whole volume is gone."

Cleanup ​

The writer processes have been stopped, the image and the test volume deleted, ~/appports-test/ deleted, and the Stickies container data used as a control restored exactly as it was. The test drive has been kept as an empty APFS drive.

最近更新