{"id":764,"date":"2026-08-01T02:24:56","date_gmt":"2026-08-01T02:24:56","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=764"},"modified":"2026-08-01T02:24:56","modified_gmt":"2026-08-01T02:24:56","slug":"linux-io-scheduler-tuning-database-vps","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/","title":{"rendered":"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The Linux I\/O scheduler decides the order in which block-device requests are processed, and on a VPS it is one of the most misunderstood performance levers in the kernel. Database workloads are especially sensitive to it: the difference between the wrong scheduler and the right one can show up as 20\u201340% swings in random-read latency, which translates directly into slower queries and higher p99 response times. This article explains how to pick, apply, and verify the I\/O scheduler for database workloads on a VPS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">First, Know What You Are Running On<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The modern kernel ships with four schedulers: <strong>mq-deadline<\/strong> (default on many distros), <strong>bfq<\/strong>, <strong>kyber<\/strong>, and <strong>none<\/strong> (a no-op pass-through). Critically, on NVMe and most cloud block storage the hardware already performs its own reordering and queueing, so a software scheduler can add overhead without adding benefit. Check what is active with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/sys\/block\/vda\/queue\/scheduler\nlsblk -d -o NAME,ROTA<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ROTA=0<\/code> means the device is non-rotational (SSD\/NVMe); <code>ROTA=1<\/code> means a spinning disk. That single value determines your starting point. On cloud VPS instances backed by network storage, the physical device is often a remote SAN or NVMe array, which changes the calculus again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Which Scheduler for Which Workload<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Scheduler<\/th><th>Best for<\/th><th>Why<\/th><\/tr><\/thead><tbody><tr><td>none<\/td><td>NVMe, cloud block storage, single-queue devices<\/td><td>Zero overhead; hardware already optimizes ordering<\/td><\/tr><tr><td>mq-deadline<\/td><td>SSD with mixed read\/write workloads<\/td><td>Guarantees read and write deadlines, limits starvation<\/td><\/tr><tr><td>bfq<\/td><td>HDD, shared disks, desktop-class latency fairness<\/td><td>Fairness-oriented; strong for many concurrent processes<\/td><\/tr><tr><td>kyber<\/td><td>Low-latency latency-sensitive apps on fast storage<\/td><td>Targets read\/write latency directly, minimal tuning<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For a typical PostgreSQL or MySQL workload on an SSD-backed VPS, the practical choice is <code>none<\/code> or <code>mq-deadline<\/code>. On NVMe, <code>none<\/code> is almost always right. On a shared or spinning-disk VPS (increasingly rare), <code>bfq<\/code> prevents one noisy process from monopolizing the disk.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Applying the Scheduler at Runtime<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can switch schedulers live, which makes A\/B testing easy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo none &gt; \/sys\/block\/vda\/queue\/scheduler<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make it permanent, add a udev rule so it survives reboots:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \/etc\/udev\/rules.d\/60-iosched.rules\nACTION==\"add|change\", KERNEL==\"vd*\", ATTR{queue\/scheduler}=\"none\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you use a kernel command-line parameter instead (<code>elevator=none<\/code>), remember that it only applies to the boot device and is ignored for devices probed later. The udev approach covers all block devices consistently.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verify with Real Benchmarks, Not Opinions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Scheduler changes are workload-dependent, so benchmark before and after. <code>fio<\/code> with a database-shaped profile is the right tool:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fio --name=db-sim --rw=randrw --rwmixread=70 --bs=8k \\\n    --iodepth=16 --numjobs=4 --size=2G --runtime=60 \\\n    --time_based --group_reporting<\/code>\n\n\n\n<p class=\"wp-block-paragraph\">70% reads at 8 KB blocks approximates OLTP traffic. Record IOPS and latency percentiles under each scheduler. A meaningful difference is one you can reproduce across multiple runs \u2014 a 5% IOPS swing is noise; a 30% p99 latency change is real. For an even more realistic test, run your actual database's workload replay (<code>pgbench<\/code> for PostgreSQL, <code>sysbench oltp<\/code> for MySQL) and watch query latency directly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Interaction with Other I\/O Settings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The scheduler is only one layer of the I\/O stack. On a VPS, three adjacent knobs change the outcome:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Queue depth (nr_requests)<\/strong> \u2014 for databases, a deeper queue helps absorb bursty OLTP traffic; on NVMe the device handles depth internally.<\/li>\n<li><strong>Filesystem mount options<\/strong> \u2014 <code>noatime<\/code> eliminates metadata writes on every read; for databases consider <code>nobarrier<\/code> only on battery-backed storage, never on a VPS without guarantees.<\/li>\n<li><strong>VM dirty ratios<\/strong> \u2014 <code>vm.dirty_ratio<\/code> and <code>vm.dirty_background_ratio<\/code> control writeback bursts. If you see periodic latency spikes, tune these before blaming the scheduler.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Remember that on most cloud VPSes the \"disk\" is remote network storage. The host-side scheduler on your instance is often less important than the storage vendor's own queueing, which is exactly why <code>none<\/code> wins so often in benchmarks \u2014 there is nothing left for the guest kernel to optimize.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When Scheduler Tuning Is Not the Answer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If your database is slow and the disk is an SSD-backed cloud volume, the scheduler is rarely the bottleneck. Check the more common culprits first: insufficient <code>innodb_buffer_pool_size<\/code> (MySQL) or <code>shared_buffers<\/code> (PostgreSQL), missing connection pooling, missing indexes, and CPU steal from an oversold host. If <code>iostat -x<\/code> shows low utilization and <code>%util<\/code> near 100%, you may be looking at queue saturation on the remote storage side \u2014 a provider-level constraint no scheduler fixes. In that case, <a href=\"https:\/\/virtualserversvps.com\/#providers\">compare VPS providers on our comparison table<\/a>, because storage quality varies far more between providers than between schedulers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also keep the rest of the memory subsystem consistent with your I\/O changes. Swap behavior, the page cache, and the I\/O scheduler all interact under pressure \u2014 tuning one in isolation while the others fight it is a common failure mode. A good monitoring setup (iostat, iotop, and a metrics dashboard) turns scheduler tuning from guesswork into a measured decision. If you are evaluating hosts for a database-heavy VPS, <a href=\"https:\/\/virtualserversvps.com\/#providers\">see the full storage specs on our VPS comparison page<\/a>, and <a href=\"https:\/\/interserver.net\/vps?id=1067805&amp;sid=virtualserversvps\" rel=\"noreferrer noopener sponsored\" target=\"_blank\">InterServer's NVMe VPS plans<\/a> are a reasonable baseline for this kind of workload.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For database workloads on modern VPS hardware, start with <code>none<\/code> on NVMe and <code>mq-deadline<\/code> on SSD, then verify with fio and a real database workload before committing. Apply changes through udev so they survive reboots, benchmark with percentile-aware tools, and keep the scheduler in context \u2014 storage vendor queueing and database memory settings usually matter more. Measure, change one variable, measure again. That discipline is worth more than any scheduler default.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Linux I\/O scheduler decides the order in which block-device requests are processed, and on a VPS it is one of the most misunderstood performance levers in the kernel. Database&#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":1,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-764","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>How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS - Virtual Servers VPS Blog<\/title>\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\/linux-io-scheduler-tuning-database-vps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS\" \/>\n<meta property=\"og:description\" content=\"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-01T02:24:56+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=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/\",\"name\":\"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-08-01T02:24:56+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS\"}]},{\"@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":"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS - Virtual Servers VPS Blog","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\/linux-io-scheduler-tuning-database-vps\/","og_locale":"en_US","og_type":"article","og_title":"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS","og_description":"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS","og_url":"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-08-01T02:24:56+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/","url":"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/","name":"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-08-01T02:24:56+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/linux-io-scheduler-tuning-database-vps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Tune the Linux I\/O Scheduler for Database Workloads on a VPS"}]},{"@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\/764","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=764"}],"version-history":[{"count":1,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/764\/revisions"}],"predecessor-version":[{"id":765,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/764\/revisions\/765"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}