This post was written in July 2017 and all benchmarks were made on High Sierra beta 17A306f. You can find benchmarks from macOS High Sierra final here

While writing a post on securing and configuring fresh macOS High Sierra installation (not yet ready), I have made some benchmarks to compare Apple’s new file system – APFS to their almost 2 decades old HFS+ (Mac OS Extended). As I require full disk encryption, I was primarily interested in encryption overhead with APFS.

Below you will find speed and latency tests on HFS+ and APFS both encrypted and unencrypted.

UPDATE 2017-07-17: ‘raw disk’ dd tests were updated with /dev/rdisk0 instead of /dev/disk0; link to APFS documentation added

Testing environment:

Hardware: 2017 MacBook Pro A1706 with i5-7267U, 16 GB 2133 RAM and AP0256J NVMe disk

OS: macOS 10.13 High Sierra Beta (17A306f)

Software used: dd, ioping, Blackmagic Disk Speed Test

macOS’ entropy – /dev/random and /dev/urandom – is known to be slow (which isn’t necessarily a bad thing), so /dev/zero was used with write tests. Read tests were also performed on files created with data from /dev/zero, altough reading and copying files filled with data from entropy was also tested and shown the same speeds as with zeroed files.

System was being restarted (but battery not disconnected) between tests to avoid caching to take place.

Raw disk

DO NOT USE THESE COMMANDS AS IT MAY DESTROY YOUR DATA! Also: as it was pointed out here , these raw disk tests were not performed properly (I have used /dev/disk0 instead of /dev/rdisk0). First 4 tests are now updated, but write speed with 4K blocks still seems a bit off… WARNING:USE THESE COMMANDS AS IT MAY DESTROY YOUR DATA!

1M write speed:

# dd if=/dev/zero of=/dev/rdisk0 bs=1m count=10000 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 10.540071 secs (994847187 bytes/sec)

1M read speed:

# dd if=/dev/rdisk0 of=/dev/null bs=1m count=10000 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 7.771463 secs (1349264584 bytes/sec)

4K write speed:

# dd if=/dev/zero of=/dev/rdisk0 bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 56.103868 secs (186899057 bytes/sec)

4K read speed:

# dd if=/dev/rdisk0 of=/dev/null bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferrd in 157.262882 secs (66676636 bytes/sec)

Unencrypted journaled HFS+

Seek rate test:

$ ioping -c 1000000000 -R /tmp --- /tmp (hfs /dev/disk1) ioping statistics --- 2.26 M requests completed in 2.85 s, 8.61 GiB read, 791.1 k iops, 3.02 GiB/s generated 2.26 M requests in 3 s, 8.61 GiB, 752 k iops, 2.87 GiB/s min/avg/max/mdev = 0 ns / 1.26 us / 1.64 ms / 2.53 us

Filesystem latency:

$ ioping -c 600 -q /tmp --- /tmp (hfs /dev/disk1) ioping statistics --- 599 requests completed in 12.1 ms, 2.34 MiB read, 49.6 k iops, 193.9 MiB/s generated 600 requests in 9.98 min, 2.34 MiB, 1 iops, 4.01 KiB/s min/avg/max/mdev = 8 us / 20.1 us / 112 us / 5.96 us

Sequential read:

$ ioping -RL /tmp --- /tmp (hfs /dev/disk1) ioping statistics --- 95.3 k requests completed in 2.99 s, 23.3 GiB read, 31.8 k iops, 7.77 GiB/s generated 95.3 k requests in 3.00 s, 23.3 GiB, 31.8 k iops, 7.76 GiB/s min/avg/max/mdev = 26 us / 31.4 us / 846 us / 5.12 us

1M write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=1m count=10000 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 7.620566 secs (1375981804 bytes/sec)

1M read speed:

$ dd if=/tmp/testfile of=/dev/null bs=1m 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 4.286424 secs (2446272139 bytes/sec)

4K write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 12.301452 secs (852400194 bytes/sec)

4K read speed:

$ dd if=/tmp/testfile of=/dev/null bs=4k 20480000+0 records in 20480000+0 records out 10485760000 bytes transferred in 4.978967 secs (2106011167 bytes/sec)





Encrypted journaled HFS+

Seek rate test:

$ ioping -c 1000000000 -R /tmp --- /tmp (hfs /dev/disk1) ioping statistics --- 2.62 M requests completed in 2.85 s, 9.99 GiB read, 919.7 k iops, 3.51 GiB/s generated 2.62 M requests in 3.00 s, 9.99 GiB, 872.9 k iops, 3.33 GiB/s min/avg/max/mdev = 0 ns / 1.09 us / 148 us / 732 ns

Filesystem latency:

$ ioping -c 600 -q /tmp --- /tmp (hfs /dev/disk1) ioping statistics --- 599 requests completed in 11.9 ms, 2.34 MiB read, 50.4 k iops, 196.9 MiB/s generated 600 requests in 9.98 min, 2.34 MiB, 1 iops, 4.01 KiB/s min/avg/max/mdev = 9 us / 19.8 us / 243 us / 9.65 us

Sequential read:

$ ioping -RL /tmp --- /tmp (hfs /dev/disk1) ioping statistics --- 116.5 k requests completed in 2.99 s, 28.4 GiB read, 38.9 k iops, 9.51 GiB/s generated 116.5 k requests in 3.00 s, 28.4 GiB, 38.8 k iops, 9.48 GiB/s min/avg/max/mdev = 20 us / 25.7 us / 928 us / 5.20 us

1M Write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=1m count=10000 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 7.634302 secs (1373506027 bytes/sec)

1M Read speed:

$ dd if=/tmp/testfile of=/dev/null bs=1m 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 4.479637 secs (2340761017 bytes/sec)

4K write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 13.153160 secs (797204620 bytes/sec)

4K read speed:

$ dd if=/tmp/testfile of=/dev/null bs=4k 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 7.054716 secs (1486347599 bytes/sec)





Unencrypted APFS

Seek rate test:

$ ioping -c 1000000000 -R /tmp --- /tmp (apfs /dev/disk1s1) ioping statistics --- 2.04 M requests completed in 2.87 s, 7.79 GiB read, 711.4 k iops, 2.71 GiB/s generated 2.04 M requests in 3.00 s, 7.79 GiB, 680.5 k iops, 2.60 GiB/s min/avg/max/mdev = 0 ns / 1.41 us / 1.11 ms / 2.50 us

Filesystem latency:

$ ioping -c 600 -q /tmp --- /tmp (apfs /dev/disk1s1) ioping statistics --- 599 requests completed in 14.1 ms, 2.34 MiB read, 42.4 k iops, 165.7 MiB/s generated 600 requests in 9.98 min, 2.34 MiB, 1 iops, 4.01 KiB/s min/avg/max/mdev = 6 us / 23.6 us / 204 us / 13.4 us

Sequential read:

$ ioping -RL /tmp --- /tmp (apfs /dev/disk1s1) ioping statistics --- 104.7 k requests completed in 2.99 s, 25.6 GiB read, 35.0 k iops, 8.54 GiB/s generated 104.7 k requests in 3.00 s, 25.6 GiB, 34.9 k iops, 8.52 GiB/s min/avg/max/mdev = 23 us / 28.6 us / 854 us / 5.99 us

1M write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=1m count=10000 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 7.642635 secs (1372008457 bytes/sec)

1M read speed:

$ dd if=/tmp/testfile of=/dev/null bs=1m 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 4.849569 secs (2162204587 bytes/sec)

4K write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 20.868400 secs (502470719 bytes/sec)

4K read speed:

$ dd if=/tmp/testfile of=/dev/null bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 4.863373 secs (2156067386 bytes/sec)

Encrypted APFS

Seek rate test:

$ ioping -c 1000000000 -R /tmp --- /tmp (apfs /dev/disk1s1) ioping statistics --- 2.05 M requests completed in 2.87 s, 7.80 GiB read, 712.3 k iops, 2.72 GiB/s generated 2.05 M requests in 3.00 s, 7.80 GiB, 682.0 k iops, 2.60 GiB/s min/avg/max/mdev = 0 ns / 1.40 us / 1.63 ms / 2.37 us

Filesystem latency:

ioping -c 600 -q /tmp --- /tmp (apfs /dev/disk1s1) ioping statistics --- 599 requests completed in 13.5 ms, 2.34 MiB read, 44.2 k iops, 172.8 MiB/s generated 600 requests in 9.98 min, 2.34 MiB, 1 iops, 4.01 KiB/s min/avg/max/mdev = 9 us / 22.6 us / 282 us / 12.4 us

Sequential read:

$ ioping -RL /tmp --- /tmp (apfs /dev/disk1s1) ioping statistics --- 106.5 k requests completed in 2.99 s, 26.0 GiB read, 35.6 k iops, 8.69 GiB/s generated 106.5 k requests in 3.00 s, 26.0 GiB, 35.5 k iops, 8.67 GiB/s min/avg/max/mdev = 19 us / 28.1 us / 626 us / 6.99 us

1M write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=1m count=10000 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 11.236624 secs (933177082 bytes/sec)

1M read speed:

$ dd if=/tmp/testfile of=/dev/null bs=1m 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 8.038967 secs (1304366611 bytes/sec)

4K write speed:

$ dd if=/dev/zero of=/tmp/testfile bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 27.725436 secs (378200001 bytes/sec)

4K read speed:

$ dd if=/testfile of=/dev/null bs=4k count=2560000 2560000+0 records in 2560000+0 records out 10485760000 bytes transferred in 10.469933 secs (1001511659 bytes/sec)

Results

As you can see, APFS’ encryption takes about 53% of file system 4K read speed, 32% of 4K write speed, 65% of 1M read speed and 47% of 1M write speed. That is a lot compared to HFS+’s accordingly: 41, 7, 4 and 0.1%



transfer – higher is better



latency – lower is better

APFS documentation

To learn about APFS advantages, check Apple File System Guide on developer.apple.com. Here’s a short features comparison:

Thanks for reading!

Related:

APFS vs HFS+: benchmarks on 2017 MacBook Pro with macOS High Sierra (final version)

How to upgrade macOS to High Sierra without filesystem change (HFS+ to APFS)

This post was written in July 2017 and all benchmarks were made on High Sierra beta 17A306f. You can find benchmarks from macOS High Sierra final here