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=1is set for both the file creation and the benchmark runs.
Measuring write performance is less tricky:
--direct=1gives results closer to raw flash speed.- Alternatively, use
--direct=0and--fdatasync=1to 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.