{"id":1408,"date":"2026-10-15T23:04:54","date_gmt":"2026-10-15T23:04:54","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=1408"},"modified":"2026-10-15T23:04:54","modified_gmt":"2026-10-15T23:04:54","slug":"benchmarking-nvme-io-throughput-kvm-vps-fio","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/","title":{"rendered":"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">&#8220;NVMe-backed storage&#8221; is a marketing line on nearly every VPS product page. Whether the storage on your specific instance actually delivers NVMe-class throughput is something you can measure in about twenty minutes with two standard tools. This article gives you a reproducible procedure for benchmarking disk I\/O on a KVM VPS, interpreting the numbers honestly, and recognising the throttling that shared storage quietly applies. Disk latency is the single biggest driver of web TTFB on a small host, so getting a real baseline matters before you blame the application. If you want the surrounding context first, the <a href=\"https:\/\/virtualserversvps.com\/blog\/fio-dd-disk-io-benchmark-vps-throttling\/\">fio and dd benchmark methodology<\/a> on the blog covers the fundamentals.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What NVMe Should Deliver Versus What a VPS Gives You<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A bare NVMe SSD can sustain hundreds of thousands of random 4K IOPS and sub-100-microsecond latency. On a KVM VPS you will not see those numbers, and that is expected: your virtual disk is a file or logical volume on the host, going through the virtio-blk or virtio-scsi stack, and sharing physical devices with other tenants. The realistic targets for a well-provisioned VPS are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Sequential read: 500\u20132000 MB\/s<\/li><li>Random 4K read: 5,000\u201350,000 IOPS depending on plan tier<\/li><li>Average 4K latency: 200 \u00b5s \u2013 2 ms<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If your numbers fall far below these, or fluctuate wildly run to run, you are either on oversubscribed storage or hitting an explicit throttle \u2014 and the method below will show you which.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Baseline: Confirm the Device and Scheduler<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Identify your block device and check the I\/O scheduler. Modern NVMe benefits from <code>none<\/code> (no scheduler); legacy <code>mq-deadline<\/code> or <code>bfq<\/code> can add latency under parallel load:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lsblk -d -o NAME,ROTA,SCHED,SIZE\ncat \/sys\/block\/vda\/queue\/scheduler\ncat \/sys\/block\/vda\/queue\/rotational<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ROTA=0<\/code> confirms the device is presented as non-rotational. If the scheduler shows <code>mq-deadline<\/code> on a modern kernel, test whether switching to <code>none<\/code> improves latency before drawing conclusions about the storage itself.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sequential Throughput with fio<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start with sustained sequential reads and writes to establish the ceiling. Use a 1 GiB file, a queue depth of 32, and direct I\/O to bypass the page cache \u2014 otherwise you are benchmarking RAM, not disk:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install fio -y\n\n# Sequential read\nfio --name=seqread --rw=read --bs=128k --direct=1 \\\n  --size=1G --numjobs=1 --iodepth=32 --runtime=30 \\\n  --time_based --group_reporting\n\n# Sequential write\nfio --name=seqwrite --rw=write --bs=128k --direct=1 \\\n  --size=1G --numjobs=1 --iodepth=32 --runtime=30 \\\n  --time_based --group_reporting<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read the <code>bw<\/code> (bandwidth) line in the output. <code>--direct=1<\/code> is non-negotiable for a meaningful result; without it, fio&#8217;s writes complete into the kernel page cache and report absurd throughput that says nothing about the backing device.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Random 4K IOPS \u2014 The Number That Predicts Real Behaviour<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Web and database workloads generate random small-block I\/O, not large sequential transfers. This is the test that matters most:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fio --name=randread --rw=randread --bs=4k --direct=1 \\\n  --size=1G --numjobs=4 --iodepth=32 --runtime=30 \\\n  --time_based --group_reporting\n\nfio --name=randwrite --rw=randwrite --bs=4k --direct=1 \\\n  --size=1G --numjobs=4 --iodepth=32 --runtime=30 \\\n  --time_based --group_reporting<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The key output fields are <code>iops<\/code> and the latency percentiles (<code>clat<\/code> \u2014 completion latency). Watch the <code>99.00th<\/code> percentile, not the average. A storage backend with a good average but a 99th-percentile latency of 50 ms will cause visible request stalls in production even though its mean looks healthy. This percentile-focused reading is the same discipline described in <a href=\"https:\/\/virtualserversvps.com\/blog\/benchmark-vps-cpu-disk-io\/\">interpreting VPS benchmarks correctly<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Corroborating with iostat During the Run<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">fio reports what the tool observed; <code>iostat<\/code> reports what the kernel saw at the device level. Running them together catches illusions. In a second terminal during the fio run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install sysstat -y\niostat -xz 1 30<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Look at <code>%util<\/code> (device utilisation) and <code>await<\/code> (average wait). If <code>%util<\/code> pins at 100% while fio reports low IOPS, the device is saturated \u2014 the bottleneck is the backing store, not your configuration. If <code>await<\/code> climbs steadily over the run, you are likely hitting a rate limit rather than a hardware ceiling.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Detecting Throttling<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Many VPS plans cap IOPS via cgroup v2 <code>io.max<\/code> or host-level token buckets. Tick-based throttling shows a signature: throughput is <em>rock-steady<\/em> at a suspiciously round number (e.g. exactly 5,000 IOPS every run) rather than varying with load. Re-run the random-read test three times and compare. Natural storage varies a few percent between runs; a throttle produces an eerily identical figure. To see it from the process side, watch your own I\/O pressure while the test runs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/proc\/pressure\/io<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A rising <code>some avg60<\/code> value during the benchmark confirms processes are stalling on I\/O \u2014 the definition of pressure. Understanding how to read PSI is covered in depth in <a href=\"https:\/\/virtualserversvps.com\/blog\/reading-psi-pressure-stall-information-vps-bottlenecks\/\">reading Linux PSI to diagnose VPS bottlenecks<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Interpreting the Results Honestly<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run every test three times and report the median, not the best run. A single lucky run overstates capability. Compare sequential versus random: if sequential is fast but random 4K is an order of magnitude worse, the storage is likely a cached tier or network-attached volume rather than local NVMe. If both are weak and 99th-percentile latency is high, the host is oversubscribed and you should test at a different hour to confirm before changing providers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Takeaway<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Benchmarking NVMe on a KVM VPS comes down to four habits: always use direct I\/O, focus on random 4K IOPS and the 99th-percentile latency rather than averages, corroborate fio with iostat at the device level, and run each test three times. That routine distinguishes genuinely fast storage from a marketing claim \u2014 and tells you exactly when a disk is the reason your application feels slow.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;NVMe-backed storage&#8221; is a marketing line on nearly every VPS product page. Whether the storage on your specific instance actually delivers NVMe-class throughput is something you can measure in about&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":2,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1408","post","type-post","status-publish","format-standard","hentry","category-performance-optimization"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat - Virtual Servers VPS Blog<\/title>\n<meta name=\"description\" content=\"&quot;NVMe-backed storage&quot; is a marketing line on nearly every VPS product page. Whether the storage on your specific instance actually delivers NVMe-class\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat\" \/>\n<meta property=\"og:description\" content=\"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-15T23:04:54+00:00\" \/>\n<meta name=\"author\" content=\"Virtual-Servers-Vps-Editor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Virtual-Servers-Vps-Editor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/\",\"name\":\"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-10-15T23:04:54+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"description\":\"\\\"NVMe-backed storage\\\" is a marketing line on nearly every VPS product page. Whether the storage on your specific instance actually delivers NVMe-class\",\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/\",\"name\":\"Virtual Servers VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\",\"name\":\"Virtual-Servers-Vps-Editor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"caption\":\"Virtual-Servers-Vps-Editor\"},\"sameAs\":[\"https:\/\/virtualserversvps.com\/blog\"],\"url\":\"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat - Virtual Servers VPS Blog","description":"\"NVMe-backed storage\" is a marketing line on nearly every VPS product page. Whether the storage on your specific instance actually delivers NVMe-class","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/","og_locale":"en_US","og_type":"article","og_title":"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat","og_description":"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat","og_url":"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-10-15T23:04:54+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/","url":"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/","name":"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-10-15T23:04:54+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"description":"\"NVMe-backed storage\" is a marketing line on nearly every VPS product page. Whether the storage on your specific instance actually delivers NVMe-class","breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/benchmarking-nvme-io-throughput-kvm-vps-fio\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Benchmarking NVMe I\/O Throughput on a KVM VPS with fio and iostat"}]},{"@type":"WebSite","@id":"https:\/\/virtualserversvps.com\/blog\/#website","url":"https:\/\/virtualserversvps.com\/blog\/","name":"Virtual Servers VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0","name":"Virtual-Servers-Vps-Editor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","caption":"Virtual-Servers-Vps-Editor"},"sameAs":["https:\/\/virtualserversvps.com\/blog"],"url":"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/"}]}},"_links":{"self":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1408","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/comments?post=1408"}],"version-history":[{"count":1,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1408\/revisions"}],"predecessor-version":[{"id":1410,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1408\/revisions\/1410"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=1408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=1408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=1408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}