Configuring Azure Virtual Machines for Optimal Storage Performance

In support, one of the most common questions we get is: How do I achieve the best disk performance for Azure virtual machines?

Platform Planning:

In the standard tier of virtual machine in Azure, the maximum IOPS is 500 per disk. When planning for a high I/O virtual machine, you also need to take into consideration the Azure storage accounts’ 20,000 total request rate limit. Therefore, we should not place more than 40 highly utilized VHDs in a storage account (20,000/500 = 40 VHDs). Azure storage is charged on a per-usage basis; you only pay for what you use. Therefore, you should always attach the maximum data disks allowed for the virtual machine size (Get-AzureRoleSize shows a MaxDataDiskCount property for each size available). The data disks should always be the maximum size allowable: one terabyte.  Locally Redundant Storage is the cheapest and highest performing choice for your storage account.

Summary of Microsoft Support’s recommendation for the Azure platform:

  • Plan for a separate single storage account for each high I/O Azure virtual machine
    • While you can safely have up to 40 VHDs per storage account, breaking each virtual machine into its own storage account allows for easier administration. You can have a maximum of 100 storage accounts per subscription
  • Locally Redundant Storage account setting
  • Attach the maximum data disks allowed for the virtual machine size
  • Data disks should always be the maximum allowable size (one terabyte)
  • Setup monitoring for storage account throttling on Azure platform

Virtual Machine Planning:

First, you need to use Storage Spaces inside your virtual machine in order to glue the disks together, overcoming the 500 IOPS per disk limitation of the Azure platform. The best Storage Spaces configuration we can use for performance is the simple storage spaces configuration. Next you need to set the number of columns, the number of columns specifies how many physical disks data is striped across, and has an impact on performance regardless of stripe and block size. For optimum performance, the number of columns must equal the number of attached data disks in Azure.

Second, you need to consider the interleave of the Storage Space. To maximize performance, ensure that the interleave value used by the storage space is at least as large as the I/Os of your workload. I/Os that exceed the interleave size are split into multiple stripes, turning one write into multiple writes, reducing performance.  In the case of database management systems, we would want to set the space interleave to be 65536 (64 KB).

Finally, we need to consider the cluster size of the Storage Spaces virtual disk. The appropriate value for most installations should be 65536 (64 KB) for partitions on which databases or log files reside.

Summary of Microsoft Support’s recommendation for an Azure virtual machine:

  • Plan your IaaS virtual machine to use Storage Spaces
  • Configure the Storage Space to use all attached data disks
  • Set the number of columns in the Storage Space to match the number of attached data disks in Azure
  • Set the Storage Space interleave at least as large as the I/Os of your workload; for SQL  use 65536 (64 KB)
  • Format the partition with a 65536 (64 KB) cluster size

Testing the I/O of disk:

A great blog to read for this question is by my co-worker, Jose Barreto. He covers this question in great depth: Using file copy to measure storage performance – Why it’s not a good idea and what you should do instead

  • Run the actual workload
  • Run a workload simulator. To simulate running SQL Server databases, you should try the SQLIO tool

Want a PowerShell script to do all of this work for you?

Automate the creation of an Azure VM preconfigured for max storage performance

Recommend further reading:

Want to reconfigure your VM’s into their own storage account?

Count VHDs Per Storage Account

Performance Best Practices for SQL Server in Azure Virtual Machines

Recommendations and Best Practices When Deploying SQL Server AlwaysOn Availability Groups in Microsoft Azure (IaaS)