Select Page

Tuning Ubuntu VM Disk I/O For Hyper-V

Tuning Ubuntu VM Disk I/O For Hyper-V

Operating systems historically expected to have direct access to the tin they were running on, and more importantly be in charge of any scheduling of the I/O.  Putting a Hyper Visor in the way makes it impossible for the VM to schedule I/O effectively as it is competing with other VMs which it knows nothing about.  Tuning Ubuntu VM Disk IO for Hyper-V in some circumstances can have a dramatically positive impact.

Understanding Linux Disk I/O SCHEDULERS

There are a number of different disk I/O schedulers to choose from.  Here’s a summary of the four ‘standard’ schedulers.

Completely Fair Queuing Scheduler (CFQ)

This scheduler works by creating a queue for each process.  After ordering the I/O queue to reduce disk seeks, these are then serviced per process in a round robin fashion.

The CFQ tries to give each process the same priority for accessing the disk.  This means if you need to prioritise one process with more I/O, this queue may not be optimal.

Deadline Scheduler

The Deadline Scheduler works with two queues, a read queue and a write queue.  Each I/O request is given a timestamp.  The scheduler then tries to order the I/O requests in the most efficient order.  Whilst dealing with the ordered I/O queue, if a request’s timestamp has expired this is processed next.

Default timeout values are 5000ms for write requests, and 500ms for read requests.  These can be changed but you can see that with the default settings the Deadline Scheduler is best for read intensive processes.  Of course these can be

Anticipatory Scheduler

This scheduler delays the dispatch of I/O requests, with the intention of aggregating requests and reducing the number of disk seek operations.  This scheduler is intended for servers with slower disks.  The downside of this scheduler is that it can have a higher I/O latency.

Noop Scheduler

This is the simplest of the schedulers.  The NOOP Scheduler works on a simple First In First Out (FIFO) basis.  Whilst it does attempt to merge similar requests, it uses the minimum amount of CPU to accomplish this task, assuming that optimisation will occur further down the path.

This is ideal for most virtual machines, as the Hyper Visor deals with disk I/O optimisation, taking into account all the VMs it is dealing with.


Before we go and change the scheduler, let’s take a look at what it’s currently set to.

From the command line type the following where [sdb] is the disk:

> cat /sys/block/[sdb]/queue/scheduler


The currently running scheduler is highlighted by squared brackets.

We can make a temporary change to the scheduler on the fly.  This will revert to it’s original settings on reboot. Alternatively we can make a permanent change via GRUB.

I would recommend making the change on the fly, and once happy with the performance increase make the change permanent.  Though if making the change due to running under a Hyper Visor (the point of this post) it’s unlikely the change to NOOP will be anything but beneficial.

Scheduler Change on the Fly

To change the scheduler on the fly, type the following where [sdb] is the disk:

> echo noop | sudo tee /sys/block/[sdb]/queue/scheduler


Then check that the change has taken place:

> cat /sys/block/[sdb]/queue/scheduler


We can see from the above that NOOP is now the selected scheduler.  The change is instant.

You can replace ‘noop’ with ‘deadline’ or ‘cfq’ as desired to put the original setting back or try other schedulers.


Once happy that your change has had a positive effect you can make the change persist through reboots.  To do this we need to make a change to the GRUB configuration file.

Using your favourite editor, edit as follows:

If using the Nano editor:

> sudo nano /etc/default/grub

or my favourite editor

> sudo vi /etc/default/grub

If you haven’t used vi before you may be better sticking with Nano.


Edit the line GRUB_CMDLINE_LINUX_DEFAULT=”……….”.  

You may find additional settings in between the quotes.  In our example above there are no additional settings.

Add “elevator=noop”  to the end of the line, or change the existing elevator=…. if present.

Before the change


After the change


This will set all disks to use NOOP.

If you have already made the change ‘on the fly’ as in the previous section, you don’t have to reboot.