A desktop setup compares NVMe SSD benchmarks on Windows and Linux, with a drive, temperature gauge, and testing checklist nearby.
Most SSD speed tests fail because of the setup, not the drive. A single CrystalDiskMark screenshot says little unless you also know the test size, the queue depth, how full the drive is, how hot it is, and what power mode the PC was in. This guide covers a repeatable benchmark for Windows and Linux built on two free tools, CrystalDiskMark for a quick readout and fio for scripted, documented runs. It applies to SATA, NVMe and external SSDs alike.

A desktop setup compares NVMe SSD benchmarks on Windows and Linux, with a drive, temperature gauge, and testing checklist nearby. 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_write is 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​

  1. Plug a laptop into AC power and choose the highest performance mode.
  2. Close browsers, launchers and sync clients, and pause Windows Update.
  3. Let the machine idle for a few minutes.
  4. Note the drive temperature. CrystalDiskInfo shows it on Windows, and smartctl -A /dev/nvme0 shows it on Linux (it needs root).
  5. On Linux, compare the negotiated PCIe link with the maximum:
Code:
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:

Code:
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​

  1. Set the count to 3 and the size to 1 GiB for a first look.
  2. Pick the drive letter, leave the profile on Default, and click All.
  3. 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​

  1. Raise the test size to 16 GiB or more and run again. If sequential writes fall noticeably, you have probably hit the cache boundary.
  2. Raise the count to 5 for steadier averages. Bigger runs write more data, so save them for the tests that matter.
  3. Look in Settings for the NVMe profile. Menu labels vary between builds, so use your own copy's profile list.
  4. Keep test data on random. Zero-filled data can inflate results on drives that compress on the fly.
  5. 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:

Code:
# 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:

Code:
[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=1 bypasses the OS page cache, so you measure the drive and not RAM.
  • ramp_time=5 discards the first five seconds.
  • stonewall stops jobs from overlapping.
  • refill_buffers=1 generates 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:

Code:
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:

Code:
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:

Code:
[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:

SymptomLikely causeWhat to check
Sequential far below rating, random normalSlot negotiated fewer lanes or a lower PCIe generationLink speed and width, motherboard manual
Everything slow and inconsistentBackground activity or thermal throttlingTask Manager, temperature, run spread
Fast start, then writes drop sharplyPseudo-SLC cache exhausted (or heat)Long write test, drive fullness
Random Q1T1 looks tinyNormal single-request behaviorConvert to IOPS and latency
CrystalDiskMark and fio differ widelyDifferent queue depth, size or engineMatch profiles, check IO depths
Results drop on batteryPower limitsPlug in, highest performance mode
External SSD stuck near an older USB speedCable, port or enclosure limitTry 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 libaio or libaio1, or switch to io_uring on a recent kernel. Check fio --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 TESTSIZE or 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_uring on modern Linux kernels to see whether software overhead was limiting high-IOPS results.
  • Add a 70/30 random read/write mix with lat_percentiles=1 and 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

  1. SSD Speed Test in 12 Steps, 60 Min (2026) - shattered.io shattered.io 2026-11-11T16:24:22+00:00
  2. CrystalDiskMark - Browse /9.0.3 at SourceForge.net sourceforge.net
  3. Download CrystalDiskMark9_0_3Shizuku.exe (CrystalDiskMark) sourceforge.net