Versions as of November 11, 2026
- CrystalDiskMark 9.0.3 is the build listed on the developer's history page. The change list for 9.0.3 shows only a security improvement to DLL loading, dated May 24, 2026. SourceForge's file listing also shows 9.0.3 as the latest download, so treat it as the current listed build. It is not a guarantee that nothing newer exists.
- fio 3.43 is the latest release on the project's GitHub releases page, tagged September 23. Distribution packages often lag, but a 3.x build is fine for the job files below.
- Windows 11 version 26H2 reached general availability on September 29, 2026, but the benchmark does not need it. Any supported Windows 11 release works, including 25H2.
Download hygiene: get CrystalDiskMark from the developer's site or the project's SourceForge page. SourceForge lists "Ads" installer variants of 9.0.3 alongside the plain ones, so read the filename before you run it. Third-party aggregators can wrap installers in extras.
What the numbers measure
An SSD test reports some mix of three quantities:
- Throughput is megabytes per second. It matters for large file copies.
- IOPS is operations completed per second. It matters for small random requests.
- Latency is how long one request takes. It matters for how responsive the system feels.
Block size and queue depth decide which of these you see. CrystalDiskMark's 9.0.x default tests are:
- SEQ 1MiB Q8T1
- SEQ 1MiB Q1T1
- RND 4KiB Q32T1
- RND 4KiB Q1T1
The NVMe profile swaps in SEQ 128KiB Q32T1 and RND 4KiB Q32T16. That information comes from the developer's change history. In these names, Q is queue depth and T is thread count.
Random Q1T1 will always look tiny next to the sequential figures. Convert it before judging it. For example, 62 MB/s of 4 KiB reads is roughly 15,000 operations per second, or about 65 microseconds each. That example is arithmetic, not a measured result.
Caches add a second layer. Many consumer drives write to a fast pseudo-SLC region first and slow down when it fills. A small test file can finish entirely inside that region. A long write test shows the sustained rate. Cache size varies by model and by how full the drive is, so do not generalize from one drive.
Step 1: Record the conditions
Create a text file next to your results and note:
- drive model, capacity and firmware
- slot or port (CPU M.2 slot, chipset slot, USB enclosure)
- filesystem and OS build
- AC or battery, and the power mode
- encryption (BitLocker, LUKS or none)
- percent of the drive in use
- cold start or just after a heavy session
A number without these conditions cannot be compared with anything later.
Step 2: Protect your data
- Test through a file on a mounted volume, never a raw device. A write test pointed at a raw device or physical drive can destroy partitions.
- fio's documentation says it aborts destructive jobs aimed at what looks like a mounted device unless
allow_mounted_writeis set. Leave that option alone. - Keep free space of at least twice the test file size. A nearly full drive also makes write results look worse than the drive deserves.
- Back up anything irreplaceable. Only run a secure erase or sanitize on a drive you have fully backed up. It is not part of routine benchmarking.
Step 3: Prepare the PC
- Plug a laptop into AC power and choose the highest performance mode.
- Close browsers, launchers and sync clients, and pause Windows Update.
- Let the machine idle for a few minutes.
- Note the drive temperature. CrystalDiskInfo shows it on Windows, and
smartctl -A /dev/nvme0shows it on Linux (it needs root). - On Linux, compare the negotiated PCIe link with the maximum:
cat /sys/class/nvme/nvme0/device/current_link_speed
cat /sys/class/nvme/nvme0/device/current_link_width
cat /sys/class/nvme/nvme0/device/max_link_speed
cat /sys/class/nvme/nvme0/device/max_link_width
If the current values are below the maximum, the slot may share lanes or run at a lower generation. Check the motherboard manual and try another slot. Windows has no equivalent built-in readout, so rely on the manual for slot details.
Step 4: Install CrystalDiskMark
Download it from the developer's site, or try winget:
winget search CrystalDiskMark
winget install CrystalDewWorld.CrystalDiskMark
Check the package ID that the search prints before installing, because identifiers can change. Then launch the program and confirm the title bar shows 9.0.3.
Step 5: Run the default profile
- Set the count to 3 and the size to 1 GiB for a first look.
- Pick the drive letter, leave the profile on Default, and click All.
- Leave the machine alone while it runs.
Read the output in this order:
- Sequential Q8T1 is the retail-box headline number.
- Sequential Q1T1 is lower because a single request cannot keep every flash channel busy.
- RND4K Q32T1 shows the controller with a healthy queue.
- RND4K Q1T1 is the smallest number on screen. It is the closest to how an operating system loads files.
Step 6: Change the size and try the NVMe profile
- Raise the test size to 16 GiB or more and run again. If sequential writes fall noticeably, you have probably hit the cache boundary.
- Raise the count to 5 for steadier averages. Bigger runs write more data, so save them for the tests that matter.
- Look in Settings for the NVMe profile. Menu labels vary between builds, so use your own copy's profile list.
- Keep test data on random. Zero-filled data can inflate results on drives that compress on the fly.
- Use the File menu's copy option to paste results as text into your notes.
Run the sequence three times with a minute of rest and keep every result, not the best one. Tight results mean a stable setup. Wide scatter points to background activity or heat.
Step 7: Install fio
On Linux:
# Debian, Ubuntu
sudo apt install fio libaio1t64
# Fedora, RHEL family
sudo dnf install fio libaio
# Arch
sudo pacman -S fio
fio --version
fio --enghelp
If libaio1t64 is not found on your release, install libaio1 instead. fio --enghelp lists the I/O engines your build supports.
On Windows, fio's own documentation says tagged-release installers have been published on GitHub since version 3.31, so use the project's releases page rather than a download portal. Open a fresh PowerShell window afterward and run fio --version. Windows uses the windowsaio engine, not libaio.
Step 8: One job file for both systems
fio expands environment variables in job files. The engine, file path and size can therefore come from your shell, and the same file runs on both platforms. Save this as ssd-suite.fio:
[global]
ioengine=${IOENGINE}
filename=${TESTFILE}
size=${TESTSIZE}
direct=1
time_based=1
runtime=30
ramp_time=5
group_reporting=1
refill_buffers=1
randrepeat=0
stonewall
[seq1m-q8t1-read]
rw=read
bs=1M
iodepth=8
numjobs=1
[seq1m-q8t1-write]
rw=write
bs=1M
iodepth=8
numjobs=1
[rnd4k-q32t1-read]
rw=randread
bs=4k
iodepth=32
numjobs=1
[rnd4k-q1t1-read]
rw=randread
bs=4k
iodepth=1
numjobs=1
[rnd4k-q1t1-write]
rw=randwrite
bs=4k
iodepth=1
numjobs=1
Add further jobs for Q1T1 sequential, Q32T1 random write and Q32T16 random by changing rw, bs, iodepth and numjobs the same way. This is a trimmed version of the full ten-job suite.
What the key settings do:
direct=1bypasses the OS page cache, so you measure the drive and not RAM.ramp_time=5discards the first five seconds.stonewallstops jobs from overlapping.refill_buffers=1generates fresh data for every write.
To match CrystalDiskMark's naming, remember that in fio iodepth applies per job. 16 jobs at depth 32 therefore means 512 outstanding requests, the same as Q32T16.
Step 9: Run on Linux
Create a test directory on the target drive, set the variables, and run:
sudo mkdir -p /mnt/test/bench && sudo chown "$USER" /mnt/test/bench
export IOENGINE=libaio TESTSIZE=8G TESTFILE=/mnt/test/bench/ssd-bench.bin
fio --output=run1.json --output-format=json ssd-suite.fio
In fio's native output, read these parts:
- IOPS and bandwidth
- the clat percentiles, because the 99th percentile and above show tail latency
- the IO depths line, which shows the queue depth actually reached
If you asked for depth 32 and the line shows depth 1, discard the result. The engine or direct I/O setting did not take effect.
Step 10: Run on Windows
The only differences are the engine and the path. fio treats a colon as a separator, so the drive letter's colon needs a backslash:
New-Item -ItemType Directory -Force -Path D:\fio-test | Out-Null
$env:IOENGINE = "windowsaio"
$env:TESTSIZE = "8G"
$env:TESTFILE = "D\:\fio-test\ssd-bench.bin"
fio --output=run1.json --output-format=json ssd-suite.fio
Create the folder first. Run it on the same drive CrystalDiskMark tested. Sequential numbers should land close together. Random numbers can differ more because the tools use different I/O paths. The guide's rule of thumb is that a repeatable gap above roughly 15 to 20 percent deserves investigation. That is a heuristic, not a standard.
Step 11: Find the SLC cache cliff
Short tests report burst speed. To see sustained speed, write one large file sequentially and log bandwidth every second:
[slc-cliff]
ioengine=${IOENGINE}
filename=${TESTFILE}
size=${CLIFF_SIZE}
rw=write
bs=1M
iodepth=8
direct=1
numjobs=1
refill_buffers=1
write_bw_log=slc
log_avg_msec=1000
Set CLIFF_SIZE larger than the drive's fast cache. A quarter of the free space is a reasonable starting point, for example export CLIFF_SIZE=200G. Check the drive's rated endurance (TBW) first. This is a heavy write test, so run it once per drive and not daily.
Plot or inspect the log. Its lines hold a timestamp in milliseconds and bandwidth in KiB/s. A sharp mid-run drop usually means the cache filled, though overheating produces a similar shape. Compare the log against your temperature readings to tell the two apart.
Afterward, delete the test file and wait at least 10 minutes. The drive does background cleanup after heavy writes. On Linux, sudo fstrim -v /mnt/test sends the trim immediately.
Step 12: Repeat, average, and save
One run is an anecdote. Run the suite three times with about 60 seconds between runs. Then compute the mean and the spread (standard deviation divided by the mean) for each job. A practical reading of the spread:
- Under about 2%: stable.
- 2 to 5%: acceptable for random workloads.
- Above 5%: background tasks, heat or a near-full drive are interfering, so fix the conditions first.
Save the results next to your notes file. After a firmware update, a slot change or a power-plan change, rerun with identical sizes and compare line by line. A change smaller than the spread means nothing.
Reading your results
Manufacturer ratings describe the best case: sequential access, deep queue, small file, empty drive and cool controller. These patterns point to likely causes:
| Symptom | Likely cause | What to check |
|---|---|---|
| Sequential far below rating, random normal | Slot negotiated fewer lanes or a lower PCIe generation | Link speed and width, motherboard manual |
| Everything slow and inconsistent | Background activity or thermal throttling | Task Manager, temperature, run spread |
| Fast start, then writes drop sharply | Pseudo-SLC cache exhausted (or heat) | Long write test, drive fullness |
| Random Q1T1 looks tiny | Normal single-request behavior | Convert to IOPS and latency |
| CrystalDiskMark and fio differ widely | Different queue depth, size or engine | Match profiles, check IO depths |
| Results drop on battery | Power limits | Plug in, highest performance mode |
| External SSD stuck near an older USB speed | Cable, port or enclosure limit | Try the shipped cable and a full-speed port |
Do not treat "90 percent of the advertised speed" as a universal pass mark. It is a reasonable sanity check for an empty drive in a healthy slot, but advertised figures and test configurations differ between vendors.
Common failure points
- fio cannot load libaio: install
libaioorlibaio1, or switch toio_uringon a recent kernel. Checkfio --enghelp. - Invalid argument with
direct=1: the filesystem does not support direct I/O, as on tmpfs and some network or FUSE mounts. Use a real local filesystem. - Windows cannot open the file: escape the colon as
D\:\...and create the folder first. - No space left on device: lower
TESTSIZEor free space. - IO depth stuck at 1: a synchronous engine or missing
direct=1. - Write speed collapses mid-test: cache exhaustion or throttling. Compare the bandwidth log with temperature, and add airflow or a heatsink if heat is the cause.
- Hard to tell what broke: change one variable at a time, such as a reboot, then background software, then slot, then tool.
Beyond the basics
- Swap the engine to
io_uringon modern Linux kernels to see whether software overhead was limiting high-IOPS results. - Add a 70/30 random read/write mix with
lat_percentiles=1and watch the 99.9th percentile. - Test steady state on drives you plan to keep under sustained load, since fresh, trimmed drives flatter themselves.
- Repeat the suite behind BitLocker or LUKS to measure what encryption costs.
- Keep every result with its notes and rerun every few months. A slow decline in random write speed is an early sign of aging or a filling drive.
FAQ
Does a speed test wear out my SSD? Write tests use a little endurance. One suite pass is small next to a typical TBW rating, but the long cache test writes much more, so do it sparingly.
Will a PCIe 5.0 SSD feel faster than PCIe 4.0 day to day? Often not for boot and app launches, which lean on low-queue random reads and CPU speed. Large copies and sustained transfers show the difference.
CrystalDiskMark or fio? CrystalDiskMark is faster to start and easy to share. fio adds latency percentiles, bandwidth logs, scripting and Linux support. Use both when you want a result you can defend.
A caveat on this guide: the fio snippets here are examples built from fio's documented behavior. They have not been run on a specific drive for this article, and any output you see will depend on your hardware.
References
- SSD Speed Test in 12 Steps, 60 Min (2026) - shattered.io shattered.io · 2026-11-11T16:24:22+00:00
- CrystalDiskMark - Browse /9.0.3 at SourceForge.net sourceforge.net
- Download CrystalDiskMark9_0_3Shizuku.exe (CrystalDiskMark) sourceforge.net