Windows systems write blocks of data to underlying storage – the size of these blocks is given various terms, for example –

  • Block size
  • Allocation unit
  • Cluster size

The important thing to consider is that this unit of allocation can have an impact on the performance of systems. By default Windows will format a disk with a standard 4KB block size. Microsoft Exchange server for example, recommends the unit size be 64KB. Microsoft recommend this for SQL server and virtual machines as well. By not setting the value correctly on an underlying disk we can generate performance problems for our system. Aligning block size with the data set being written can help to ensure efficient IO processing. If we consider SQL server which uses a 64KB extent (which is it’s basic unit, made up of eight, 8KB pages) we can most effectively format the disk with a 64KB block size. Assuming this is a locally attached disk we can then have Windows write the extent as one contiguous block rather than having to split it up into say 4KB default sized blocks. Imagine taking that 64KB extent and having to split that single IO into 16 smaller IO writes – not very efficient.

If we are writing to SAN storage we also want to make sure the block size (or whatever the vendor calls it) is also appropriate, again to try and avoid split IO writes and to ensure performance. It’s a big topic to discuss but I will end here and move on to how we can retrieve this information from our servers.

 

PowerShell Commands

Microsoft are deprecating the Get-wmiObject cmdlet in favour of the Get-cimInstance cmdlet. I have provided both as a reference in case you are doing this on older systems. Note that the value is described as ‘BlockSize’.

PS C:\> Get-WmiObject -Class Win32_Volume | Select-Object Label, BlockSize | Format-Table -AutoSize
PS C:\> Get-CimInstance -ClassName Win32_Volume | Select-Object Label, BlockSize | Format-Table -AutoSize

 

Example output –

PS C:\> Get-CimInstance -ClassName Win32_Volume | Select-Object Label, BlockSize | Format-Table -AutoSize

Label                  BlockSize

-----                  ---------

4096

bsa_sqlinfra01_db_vv        4096
bsa_sqlinfra01_logs_vv      4096
bsa_sqlsp_db_vv            65536
bsa_sqlsp_logs_vv          65536
Recovery                    4096

 

DOS Commands

We can make use of the fsutil amd DiskPart commands. Note that in fsutil the value is ‘Byte Per Cluster’ with a 64KB value while in DiskPart it is called ‘Allocation Unit Size’.

PS C:\> fsutil fsinfo ntfsinfo p:

NTFS Volume Serial Number :       0x5840d42e40d4151a
NTFS Version   :                  3.1
LFS Version    :                  2.0
Number Sectors :                  0x000000007ffbefff
Total Clusters :                  0x0000000000fff7df
Free Clusters  :                  0x0000000000459424
Total Reserved :                  0x0000000000000000
Bytes Per Sector  :               512
Bytes Per Physical Sector :       512
Bytes Per Cluster :               65536
Bytes Per FileRecord Segment    : 1024
Clusters Per FileRecord Segment : 0
Mft Valid Data Length :           0x000000000e840000
Mft Start Lcn  :                  0x000000000000c000
Mft2 Start Lcn :                  0x0000000000000001
Mft Zone Start :                  0x0000000000cf4180
Mft Zone End   :                  0x0000000000cf4c80
Resource Manager Identifier :     0C567257-18F9-11E5-80CE-00155DAEB03C

I will use the DiskPart utility to list all of the volumes attached to this server, then I will select a volume and use the ‘filesystems’ command to display the required information. As mentioned the value is now described as ‘Allocation Unit Size’.

DISKPART> list vol

Volume ###  Ltr  Label        Fs     Type        Size     Status     Info

----------  ---  -----------  -----  ----------  -------  ---------  --------

Volume 0     C                NTFS   Partition     59 GB  Healthy    Boot
Volume 1         Recovery     NTFS   Partition    300 MB  Healthy    Hidden
Volume 2                      FAT32  Partition     99 MB  Healthy    System
Volume 3     P   bsa_sqlsp_d  NTFS   Partition   1023 GB  Healthy
Volume 4     Q   bsa_sqlsp_l  NTFS   Partition    199 GB  Healthy
Volume 5     F   bsa_sqlinfr  NTFS   Partition    499 GB  Healthy
Volume 6     G   bsa_sqlinfr  NTFS   Partition    199 GB  Healthy

DISKPART> select vol 3

Volume 3 is the selected volume.

DISKPART> filesystems

Current File System

Type                 : NTFS
Allocation Unit Size : 64K
Flags : 00000000

File Systems Supported for Formatting

Type                 : NTFS (Default)
Allocation Unit Sizes: 512, 1024, 2048, 4096, 8192, 16K, 32K, 64K (Default)

Type                 : REFS
Allocation Unit Sizes: 64K (Default)

DISKPART>

 


 

As you can see Microsoft lack consistency in describing this attribute which is rather frustrating but such is the way of the IT world. It’s always important to check that you are formatting storage with the correct block size to avoid split IO and misalignment issues. I have seen some vendors (especially all flash array sellers) telling administrators not to worry because their system is ‘so fast’ any overhead or inefficiencies caused can be compensated for by the systems speed. Personally I hate this notion and fully believe everything should be optimised and deployed according to best practices to get the most out of the system.