How to increase IOPS for standard Azure VM

Recently I faced a performance problem with one of my systems based on several standard Azure virtual machines. The problem was connected with high disk response time during heavy workload. Of course, the easiest solution was to move all VMs to a premium storage account. But it could increase my expenses. So, I started to investigate other ways to do it and found one. 

I found an article at MSDN site which describes best practices of increasing disk performance. The recommendation is based on several points:

  • There is a limit of 500 IOPS  for one standard virtual disk
  • You can increase disks performance by adding more virtual disks and creating a striped volume
  • According to Azure billing system, you will pay only for used space, not for requested space.

So, according to the article, you should add as much disks as possible for you virtual machine’s type, create a stripped volume and move all your workload to this disk. And your expenses won’t increase. So, let’s check how this solution works in practice.

To check disk performance I’m going to use Microsoft disk tool – Diskspd.  This utility can produce high disk load with several threads. The heaviest operation for a disk is writing. So, we will test it with the following command line:

diskspd.exe -c1024M -d90 -W30 -w100 -t8 -o64 -b8k -r -h -L c:\testfile.dat

There are the test params:

duration: 90s
warm up time: 30s
cool down time: 0s
measuring latency random seed: 0
path: ‘c:\testfile.dat’
think time: 0ms
burst size: 0
software and hardware write cache disabled
performing write test
block size: 8192
using random I/O (alignment: 8192)
number of outstanding I/O operations: 64
thread stride size: 0
threads per file: 8
using I/O Completion Ports IO
priority: normal

At the first step I’ll test the performance of the system disk:

Total IO

thread |       bytes     |     I/Os     |     MB/s   |  I/O per s |  AvgLat  | LatStdDev |

———————————————————————–      0 |        26476544 |         3232 |       0.28 |      35.92 | 1783.654 | 433.444 |

1 |        26460160 |         3230 |       0.28 |      35.89 | 1782.521 |  438.902 |

2 |        26746880 |         3265 |       0.28 |      36.28 | 1771.207 |  430.423 |

3 |        26542080 |         3240 |       0.28 |      36.01 | 1781.814 |  431.302 |

4 |        26501120 |         3235 |       0.28 |      35.95 | 1787.043 |  430.844 |

5 |        26484736 |         3233 |       0.28 |      35.93 | 1783.054 |  424.963 |

6 |        26165248 |         3194 |       0.28 |      35.49 | 1804.594 |  434.600 |

7 |        26435584 |         3227 |       0.28 |      35.86 | 1785.527 |  431.839 |
———————————————————————–

total:         211812352 |        25856 |       2.24 |     287.33 | 1784.880 |  432.135

Our system disk can provide 287 IPOS for writing. Of course, it’s not enough for heavy loaded systems.

Now lets add one new virtual disk and check its performance. All test params will be the same.

Total IO

thread |       bytes     |     I/Os     |     MB/s   |  I/O per s |  AvgLat  | LatStdDev |

———————————————————————–

0 |        48332800 |         5900 |       0.51 |      65.55 | 1020.432 | 2188.976 |

1 |        48193536 |         5883 |       0.51 |      65.36 | 1037.424 | 2292.571 |

2 |        48046080 |         5865 |       0.51 |      65.16 | 1040.323 | 2366.275 |

3 |        44515328 |         5434 |       0.47 |      60.37 | 1237.349 | 3824.367 |

4 |        41615360 |         5080 |       0.44 |      56.44 | 1455.779 | 4888.766 |

5 |        34095104 |         4162 |       0.36 |      46.24 | 1723.184 | 6884.812 |

6 |        50561024 |         6172 |       0.54 |      68.57 |  931.849 |  271.245 |

7 |        50233344 |         6132 |       0.53 |      68.13 |  937.284 |  278.582 |

———————————————————————–

total:         365592576 |        44628 |       3.87 |     495.84 | 1143.117 | 3326.473

New empty disk provides 495 IOPS which is the same as stated in the documentation.

Next I added 8 1Tb disks, created a striped volume and formatted it with 64kb block size:

stripe-array

There is the test result:

Total IO

thread |       bytes     |     I/Os     |     MB/s   |  I/O per s |  AvgLat  | LatStdDev |

———————————————————————–

0 |       338919424 |        41372 |       3.59 |     459.68 |  144.295 |  378.064 |

1 |       335331328 |        40934 |       3.55 |     454.82 |  145.886 | 379.168 |

2 |       340197376 |        41528 |       3.60 |     461.42 |  143.871 | 373.682 |

3 |       337313792 |        41176 |       3.57 |     457.51 |  144.993 |  382.608 |

4 |       337846272 |        41241 |       3.58 |     458.23 |  144.898 | 381.561 |

5 |       339148800 |        41400 |       3.59 |     459.99 |  144.229 | 378.508 |

6 |       333553664 |        40717 |       3.53 |     452.41 |  146.668 | 381.966 |

7 |       339025920 |        41385 |       3.59 |     459.83 |  144.228 | 375.175 |

———————————————————————–

total:        2701336576 |       329753 |      28.62 |    3663.88 |  144.878 | 378.842

As a result, we got almost 8*500 IOPS as it was mentioned in the best practices.

It means that if your system will have even medium workload, it’s better to create striped volume to increase performance. In any case, it won’t cost you extra money.

2 thoughts on “How to increase IOPS for standard Azure VM

Leave a comment