NVMe vs SSD VPS: E Really Matter?
NVMe fit beat SATA SSD for IOPS and latency, but VPS hypervisor and neighbours fit limit you. Use fio to measure your real storage speed.
NVMe dey matter for VPS?
NVMe dey matter for VPS when your software dey send plenty small read and write operations and dey wait make each one finish. E no change much for site wey dey serve cached pages, or for program wey dey spend most of im time waiting for network. The storage medium na only one factor. The hypervisor wey dey in front of the disk, plus other guest systems wey dey share the same host, go set the maximum performance wey you actually get.
Wetin NVMe change, and wetin e no change
NVMe (non-volatile memory express) no be kind of flash memory. Na the protocol and connection wey dey used reach the flash. NVMe device dey sit for PCIe (peripheral component interconnect express) lanes and e dey speak NVMe. SATA (serial ATA) SSD dey sit for SATA link and e dey speak AHCI (advanced host controller interface). The memory chips wey hold your bytes fit be the same for both.
Two things dey different, and both concern the command path, no be the storage itself.
Queues. AHCI give kernel one command queue wey fit hold 32 commands. NVMe allow thousands of queues, normally one for each CPU core, and each one deep pass 32. One process wey dey read one block at a time no go notice the difference. Database wey get 64 reads outstanding fit notice am: for SATA, the 33rd request go wait for queue slot before the device even see am, but NVMe device go accept all of dem and work on dem together.
Link width. SATA III link dey run for 6 Gbit/s, wey be about 550 MB/s of real data after protocol overhead. This na fixed ceiling, no matter the flash wey dey behind am. Four PCIe lanes fit carry several gigabytes per second, so the link no longer be the limit.
Latency na where expectation dey usually wrong. For queue depth 1, meaning say na one request dey in flight, SATA SSD dey answer 4k read for about 100 to 150 microseconds. NVMe dey answer for about 80 to 100. Both fast, and nothing wey you run go notice the difference for one request. The gap dey open when concurrency dey. Queue depth, wey be the number of requests wey dey in flight at the same time, na the setting wey decide whether the two media go look alike or very different.
Network block storage na third class wey get different physics. Write dey cross network go storage cluster, and e dey receive acknowledgement only after the cluster hold am, so dem dey measure the latency for milliseconds instead of microseconds. Wetin you buy with that latency na durability: the volume go outlive the host wey e attach to, and you fit take snapshot of am and resize am.
Published figures wey people dey usually quote: NVMe, SATA SSD and network storage
The data behind this chart
[
{
"disk": "Local NVMe SSD",
"iops_4k_read": "184,000",
"p99_latency_ms": 0.4,
"seq_read_mbps": "3,400"
},
{
"disk": "Local SATA SSD",
"iops_4k_read": "90,000",
"p99_latency_ms": 1.2,
"seq_read_mbps": "550"
},
{
"disk": "Network block storage",
"iops_4k_read": "12,500",
"p99_latency_ms": 6.5,
"seq_read_mbps": "250"
}
]Dem dey commonly quote local NVMe device at 184,000 random 4k read IOPS (input/output operations per second) for queue depth 32. For the same test, SATA SSD dey near 90,000, because the single AHCI queue and the 6 Gbit/s link dey limit am. Network block storage usually dey limited by the provider, no be the hardware, and 12,500 na common documented ceiling.
Latency dey show the same thing for the unit wey your users dey feel. The p99 read latency, meaning the slowest 1 percent of requests, dey around 0.4 ms for local NVMe and 1.2 ms for SATA. Once network enter the path, e become 6.5 ms, wey pass the NVMe figure by more than ten times.
Sequential reads get the biggest difference, but dem least useful: 3,400 MB/s against 550 MB/s. Almost nothing for server dey read one large file from beginning reach end at full speed. The random column and latency column describe wetin database, mail queue or package manager really dey do.
Where these figures come from, and why yours will differ
The 3 rows na vendor datasheet figures for the local devices and documented per-volume limits for network storage, current as of July 2026 and rounded. Dem assume 4k block size, random reads, queue depth 32 and one job, wey be the kind test vendor dey publish. Your VPS na guest for shared host, so the same test for your box normally go return less, and the result fit change between runs. Read these rows as the shape of the difference between the three classes, no be as target wey you must reach.
Which workloads dey notice the disk
One rule explain all of dem: workload dey notice the disk only when e dey wait for the disk. Linux dey keep recently used file data for RAM, inside page cache, so the second read of a file no reach storage again. If the working set, meaning the data wey dey use, fit inside RAM, reads become memory reads after the first pass. Writes dey different. Any write wey application flush with fsync() must dey for stable storage before application fit continue.
Work wey dey commit. PostgreSQL, MySQL and SQLite dey call fsync() or fdatasync() when dem commit, and every commit dey wait for the device to answer. So, the commit rate of one connection depend on write latency, no be bandwidth. Device wey flush for 0.2 ms fit allow much more commits per second than one wey take 5 ms, and no amount of throughput fit change that. MySQL dey talk am for error log when flush no fit keep up:
[Note] InnoDB: page_cleaner: 1000ms intended loop took 4589ms. The settings might not be optimal.PostgreSQL dey report am for the checkpoint lines. For there, large sync= value mean say the flush itself slow:
LOG: checkpoint complete: wrote 8192 buffers (25.0%); write=27.694 s, sync=11.207 s, total=39.001 sWork wey dey touch plenty small files. Every file get metadata operations wey one large sequential read no get. npm install, git clone of big repository, unpacking container images, Maildir mail store and backup wey dey walk large tree all dey spend their time on small random access. A restic backup job for VPS dey read and hash every file wey e never see before, so the wall-clock time of backup over one million files dey follow random read latency closely. Na the same thing with du -sh, wey dey read metadata and nothing else.
Databases wey outgrow RAM dey belong here too. Once index no fit inside page cache again, every lookup become random read, and disk enter the critical path again.
Which workloads no dey notice the disk
A blog or small company website. The pages small, page cache hold all of dem after the first request, and CPU for rendering or bandwidth for assets na the limit. A LAMP stack for Ubuntu 24.04 wey dey serve low-traffic site dey do almost no disk IO after e don warm up.
Media streaming. One 4K stream for 40 Mbit/s dey read 5 MB/s. Ten of dem dey read 50 MB/s, and even network block storage fit serve this without stress. Jellyfin media server for VPS dey limited by your network egress allowance and CPU when e dey transcode, not by the storage medium.
Local model inference. Running Ollama for VPS to self-host LLM dey read the model file once, then e dey work for RAM. NVMe fit reduce load time for 20 GB model from minutes to seconds. E no change tokens per second, because memory bandwidth and CPU dey determine am.
Anything wey dey wait for external service. Worker wey dey spend 800 ms per job for HTTP request no go faster because you use better disk.
Why hypervisor matter as much as the medium
You no dey talk to the device. You dey talk to virtual disk wey hypervisor present, usually through virtio, and several decisions for that layer matter pass NVMe against SATA.
You no fit see the medium from inside the guest. lsblk -d -o NAME,ROTA,SIZE,MODEL dey show vda with empty model, because virtio no dey pass drive identity through. cat /sys/block/vda/queue/rotational dey report wetin hypervisor advertise, so 0 for there no be proof say na flash. nvme list, from the nvme-cli package, no dey list anything for most VPS even when host full of NVMe drives, because your disk na virtio device and no be NVMe device. Plan wey say NVMe usually dey describe wetin host get. Your volume fit still dey network attached.
Host cache mode fit change the numbers pass the medium. With writeback caching for host, guest fsync() fit return as soon as host don keep the data for its own RAM. That fit produce benchmark result wey no physical device fit deliver. E also mean say host crash fit lose writes wey your database believe say safe. With cache mode none, the numbers lower and honest.
Caps and burst credits. Plenty providers dey cap IOPS per volume or per plan, and plenty network volumes dey use burst allowance. Burst allowance na pool of credits: volume dey run fast while credits still dey, then e drop to much lower baseline. The symptom easy to recognise. Import or restore fit run fast for several minutes, then e slow down sharply and remain slow, without anything change for your configuration. You don use the credits.
Neighbours. For shared host, wetin other guests dey do fit change your disk latency. Na why you need measure more than once. Run the same test for morning and again for evening, then compare the spread. For busy host, difference between 2 runs on the same volume often pass the published difference between 2 media.
How to measure the disk wey your VPS really get
Install fio, the standard IO benchmark, then measure am. First, make you note these three cautions. The test go create file, so e go use disk space and count against any IOPS allowance wey dem dey bill you for. Make the runs short. No run am for full queue depth against volume wey dey serve live traffic, because you go dey compete with your own application.
sudo apt update && sudo apt install -y fio ioping sysstat
cd /var/tmpRandom read for queue depth 32, wey be the depth vendors dey quote:
fio --name=randread --filename=fio.test --size=1G --bs=4k --rw=randread \
--ioengine=libaio --direct=1 --iodepth=32 --numjobs=1 \
--runtime=30 --time_based --group_reportingThe line wey matter start with read:
read: IOPS=184k, BW=719MiB/s (754MB/s)(21.1GiB/30001msec)--direct=1 dey bypass the guest page cache, so the result describe the device instead of your RAM. If you leave am out, you go measure memory, and e go return number wey no disk fit reach. Use --size=4G or larger if you get the space, because 1G file fit stay entirely inside the host cache and make the result look better than e really be.
Queue depth 1 show raw latency, wey be wetin single-threaded process dey feel:
fio --name=lat --filename=fio.test --size=1G --bs=4k --rw=randread \
--ioengine=libaio --direct=1 --iodepth=1 --runtime=30 --time_basedThe commit test dey predict database behaviour. E dey write 4k and call fdatasync() after every write, so the reported rate include the flush:
fio --name=commit --filename=fio.test --size=1G --bs=4k --rw=randwrite \
--ioengine=psync --fdatasync=1 --runtime=30 --time_based
rm -f fio.testThe IOPS figure from that run dey close to the highest number of small transactions per second wey one database connection fit commit, because commit dey wait for the same flush.
For quick sample without fio:
ioping -c 20 .--- . (ext4 /dev/vda1) ioping statistics ---
19 requests completed in 4.13 ms, 76 KiB read, 4.60 k iops, 17.9 MiB/s
min/avg/max/mdev = 174.2 us / 217.6 us / 386.1 us / 51.3 usThe mdev value, the mean deviation, dey important as the average. Large deviation for idle box mean say storage backend dey shared and busy.
Wetin the result mean
As of July 2026, these readings reasonable for small VPS. Tens of thousands of 4k random read IOPS for queue depth 32, with queue depth 1 latency below about 0.3 ms, match local flash. If queue depth 1 latency dey several milliseconds, e mean say network path dey involved, no matter wetin dem call the plan. Sequential reads wey stop near 550 MB/s na sign of SATA link. If the number far pass wetin any single device fit do, caching dey somewhere for the path, almost always for the host.
To see wetin your live workload dey do to the disk:
iostat -x 1 3
vmstat 1 5
cat /proc/pressure/ioFor iostat -x output, read r_await and w_await. Dem show the average milliseconds wey request wait, and aqu-sz, the average queue length. Ignore %util for virtual disk. E report the percentage of time wey at least one request dey outstanding. This no tell you anything about saturation for device wey fit serve many requests at once. So %util of 100 together with r_await of 0.2 ms mean say the busy disk still healthy. For vmstat, the wa column na the percentage of CPU time wey dey wait for IO. If /proc/pressure/io dey your kernel, the some avg10= value na the share of the last 10 seconds when at least one task dey stalled on IO. This na the most direct answer to whether storage be your bottleneck.
Wey a disk-bound VPS dey look like
High load average with idle CPU and big wa for vmstat mean say processes dey queue behind the disk. The clearest kernel signal na this message for dmesg -T:
INFO: task jbd2/vda1-8:194 blocked for more than 120 seconds.That line dey show because one kernel thread wait pass two minutes make storage answer, so hung task watchdog log am. jbd2 na the ext4 journal thread, meaning say the whole filesystem dey wait, no be one program wey misbehave. For VPS, e usually point to storage backend or IOPS allowance wey don finish.
The application symptoms follow the same pattern. Median response time remain acceptable, but the slowest requests dey grow one long tail, because na only requests wey touch disk dey pay the cost. apt upgrade dey stay for Unpacking for minutes, because dpkg dey flush data as e dey write. git status for big repository fit take seconds. These na metadata and flush costs, so more bandwidth no go help.
Wetin to do when disk na the limit
Buy RAM before you buy IOPS. If the working set fit inside page cache, reads no longer need reach disk at all. Doubling memory often better pass moving to faster storage class, and e usually cost less.
Reduce the number of flushes, where the data allows am. For PostgreSQL, synchronous_commit = off fit make commit return before the write reach disk. You fit lose the last fraction of a second of transactions if server crash. Database no go corrupt, because write-ahead log still dey write in order. This trade make sense for analytics copy but e no make sense for payments. innodb_flush_log_at_trx_commit = 2 for MySQL na the same trade.
Batch small files. Transfer or backup of a million small files dey spend most time on cost wey each file get, so archive dem first and move one stream. For storage wey get high latency, this dey faster than copying the tree file by file.
Make discard continue to work for thin volumes. For thin provisioned storage, backend no know say block don free until filesystem tell am. Volume wey never trim go slowly lose write performance. Ubuntu ships a weekly timer for this:
systemctl status fstrim.timer
sudo fstrim -avfstrim -av prints the bytes wey e trim for each mount point. If message say discard operation no dey supported, e mean virtual disk no pass discard through to host, so you no get anything to fix.
No bother tune IO scheduler. For virtio disk, cat /sys/block/vda/queue/scheduler usually dey show none already, and the real scheduling dey happen for host, where you no get access. No bother with noatime too: Ubuntu mounts with relatime by default, and this already avoid almost every atime write.
Choosing a plan
Pay for NVMe when database, mail server, CI runner, or package-heavy build dey run for the box. No pay extra money for cached website or app wey most of e time dey wait for external calls. If you no sure, disk probably no be your limit, because most small VPS workloads first dey run out of RAM or bandwidth.
Measure am on day one, while you dey work through the first ten minutes on a new VPS, and keep the output for one file. Baseline na how you go later prove say host don slow down, instead of your code. Prefer providers wey clearly write the storage class and any IOPS cap. If plan talk say NVMe, but read with queue depth 1 dey take 4 ms, you get network storage for host wey use NVMe. Na fair thing to sell, but na different thing to buy.
FAQ
NVMe always fast pass SATA SSD for VPS?
No. For queue depth 1, dem dey close, roughly 80 to 150 microseconds for one 4k read, and single-threaded program no fit tell the difference. NVMe dey pull ahead when many requests dey in flight, because AHCI get one queue wey deep reach 32 commands, while NVMe get thousands of queues wey deeper. For shared host, load from other guests fit change your latency pass the storage medium itself, so measure your own volume with fio instead of relying on the plan name.
How I fit check whether my VPS really dey use NVMe?
You no fit check am directly, because virtio dey hide the physical device. lsblk dey show vda without model string, nvme list no dey return anything, and /sys/block/vda/queue/rotational dey report only wetin the hypervisor advertise. Measure the behaviour instead. Random 4k read for queue depth 1 wey dey below about 0.3 ms mean say local flash dey. Several milliseconds mean say network hop dey inside the path. Sequential reads wey stop near 550 MB/s show say na SATA link.
NVMe go make my website load faster?
Normally, no. After the first request, Linux dey serve the files from page cache for RAM, so disk no dey do work. For small VPS, application CPU time and bandwidth normally dey limit page speed. Disk go return to the critical path if the site dey write for every request. For example, database-backed cart wey dey commit often go wait for every flush to complete.
Wetin be good fio result for VPS?
As of July 2026, small VPS for local flash normally dey return tens of thousands of 4k random read IOPS for queue depth 32, with queue depth 1 latency below 0.3 ms. Network block storage normally dey return a few thousand IOPS with latency of a few milliseconds. Run the test three times for different hours. Big difference between the runs tell you more than the average, because e show how much other guests for the host dey affect you.
I suppose put my database for network block storage?
You fit, and many managed services dey do am, but the commit path go pay for am. Every flush dey cross the network, so one connection go commit fewer small transactions per second than e for do for local flash. In exchange, you get durability wey fit survive host failure. If you choose network storage for write-heavy database, group the work into larger transactions so fewer flushes fit carry more rows.