Skip to content
Summer 2026: 20% off 12-month terms with code ATLAS10 stacked on top
Engineering 7 min read

NVMe vs SATA SSD on a VPS: benchmarks from our own fleet

Real fio numbers from production nodes, why IOPS marketing is mostly noise, and how to tell whether your disk is actually the bottleneck.

ML

Marek Lindqvist

Infrastructure Security

Published

Quick answerFor virtual machines, NVMe's advantage is latency under concurrency, not peak throughput. Sequential numbers look 5-6x better on paper; the number you actually feel is 4K random read latency at queue depth 32, where our NVMe nodes land at ~0.11 ms versus ~0.74 ms on the SATA fleet we retired in 2023.

Test methodology

Run on production nodes in Frankfurt during a low-traffic window, from inside a 4 vCPU / 8 GB guest, so these are numbers a customer could reproduce โ€” not host-level figures with the guest overhead removed.

fio --name=randread --ioengine=libaio --direct=1 --bs=4k \
    --iodepth=32 --size=4G --runtime=60 --numjobs=4 --group_reporting --rw=randread

4K random read, QD32

StorageIOPSBandwidthAvg latencyp99 latency
NVMe RAID-10 (current)287,0001,121 MB/s0.11 ms0.38 ms
SATA SSD RAID-10 (retired 2023)43,200169 MB/s0.74 ms3.10 ms
Network block storage (typical cloud)16,000*62 MB/s1.90 ms11.4 ms

* Capped by the provider's per-volume IOPS limit, not by the hardware.

4K random write, QD32

StorageIOPSAvg latencyp99 latency
NVMe RAID-10168,0000.19 ms0.71 ms
SATA SSD RAID-1031,5001.02 ms5.80 ms

What that means in workload terms

  • PostgreSQL, 8 GB dataset, pgbench 50 clients: 4,180 tps on NVMe vs 940 tps on SATA. The database is latency-bound on WAL flushes, which is exactly NVMe's strength.
  • Windows Server boot to usable desktop: 19 s vs 41 s. Not important once, very noticeable when you reinstall or reboot regularly.
  • npm install on a large monorepo: 47 s vs 112 s. Package managers are a flood of tiny random writes.
  • Serving static files from nginx: essentially identical. Once the working set is in page cache, the disk is irrelevant โ€” do not pay for NVMe to solve a problem you do not have.

Why "1,000,000 IOPS" in an ad means nothing

Three reasons that number is usually theatre:

  1. It is the node's total, not yours. A node hosting 40 guests shares that pool. Your share depends entirely on what the neighbours are doing.
  2. It is a burst figure. Consumer-class NVMe uses an SLC cache; once it is full, sustained write speed can fall by 70%. Enterprise drives with power-loss protection hold their numbers, and cost about 3x more per terabyte.
  3. Queue depth is unstated. QD256 with 16 jobs produces a big number that no real application generates.

The honest metric is p99 latency under a realistic queue depth, sustained for at least ten minutes. That is why the tables above include p99.

Is your disk actually the bottleneck?

Linux

iostat -xz 1        # %util near 100 with high await = disk-bound
vmstat 1            # high 'wa' in the CPU columns = waiting on I/O
iotop -oPa          # which process is responsible

Windows

Get-Counter '\PhysicalDisk(_Total)\Avg. Disk sec/Read' -Continuous
# Sustained above 0.020 s (20 ms) means the disk is the constraint.

If await is low and %util is low but the app is still slow, the disk is innocent โ€” look at CPU steal, memory pressure or a network round trip.

What we run

Every RDPForge node uses enterprise NVMe (Samsung PM9A3 / Micron 7450 class) in RAID-10 with power-loss protection and hardware-accelerated parity. There is no SATA tier left in the fleet โ€” the last SATA node was retired in November 2023 โ€” and there is no network-attached block storage anywhere, so your disk is always physically in the machine running your VM.

#nvme#storage#benchmarks#performance
ML

Marek Lindqvist

Infrastructure Security

Runs our hardening baselines and incident response. Previously a network engineer at a Nordic transit provider.

Put this into practice for $5 a month

Windows RDP from $12/month, Linux VPS from $5/month, delivered in about four minutes with a 72-hour money-back guarantee.