Recently, I tried benchmarking a USB stick using fio, and it turned out to be a cursed journey. To save you some time, here are the quirks I encountered and how I worked around them.
macOS employs aggressive file caching, and even with --direct=1
, there’s no guarantee that reads or writes will bypass the Unified Buffer Cache. This behavior is discussed in this GitHub comment.
The XNU kernel ignores direct I/O requests if the chunk size is less than 16,384 bytes. In practice, even with larger chunk sizes, I often had to manually flush or purge the cache to get reliable results, as noted in this issue.
For accurate read performance measurements:
- Pre-create the test file using the same flags. Use a short runtime (e.g.,
--runtime=1s
) and a large chunk size (e.g.,--size=1M
). - Run
sudo purge
. - Then run the actual benchmark with
--allow_file_create=0
, pointing to the same file. - Make sure
--direct=1
is set for both the file creation and the benchmark runs.
Measuring write performance is less tricky:
--direct=1
gives results closer to raw flash speed.- Alternatively, use
--direct=0
and--fdatasync=1
to simulate real-world usage more accurately, similar to what AmorphousDiskMark and Finder report.
That should wrap it up. If you are coming from CrystalDiskMark or AmorphousDiskMark, there’s a script that automates the tests for you. Do read through the script and use it at your own risk.