Skip to main content

How to Get the Cluster Size of a Volume in Batch Script

The Cluster Size (also called Allocation Unit Size) is the smallest block of space the file system uses to store data. If your cluster size is 4 KB and you save a 1-byte text file, it still consumes 4 KB of disk space. Understanding this is critical for optimizing storage: large clusters are faster for big files (like video editing or databases) but waste space with small files; small clusters are space-efficient but slower for bulk I/O. A Batch script can query the cluster size of any volume, providing the intelligence needed for storage tuning, format planning, and performance optimization.

This guide will explain how to query the allocation unit size.

Why Cluster Size Matters

Cluster SizeSpace EfficiencyI/O PerformanceBest For
512 bytesMaximum (minimal waste)Slowest (many small reads/writes)Rarely used
4 KB (4096)Good, default for most NTFSGood, balanced for mixed workloadsGeneral purpose, OS drives, office work
8 KBModerateBetter for medium filesFile servers with mixed content
16 KBLowerGood for large filesMedia storage
64 KBLowest (significant waste with small files)Best for sequential I/OSQL Server, Hyper-V, virtual disks

The space waste problem:

Every file, no matter how small, occupies at least one cluster. With 64 KB clusters, a 1-byte file wastes 65,535 bytes. A folder with 10,000 small log files (each under 1 KB) would waste approximately 625 MB. Conversely, with 4 KB clusters, a 10 GB database file requires 2,621,440 allocation entries in the MFT, whereas 64 KB clusters need only 163,840 entries, reducing metadata overhead and improving sequential read/write speed.

Method 1: Check a Specific Drive

This method queries the cluster size of a specific volume and provides context about what the size means for different workloads.

Implementation

@echo off
setlocal

set "Drive=%~1"

if "%Drive%"=="" (
echo Usage: %~nx0 ^<drive_letter^>
echo.
echo Examples:
echo %~nx0 C
echo %~nx0 D
endlocal
exit /b 1
)

:: Normalize drive letter
set "DriveLetter=%Drive:~0,1%"
set "DriveColon=%DriveLetter%:"

if not exist %DriveColon%\ (
echo [ERROR] Drive %DriveColon% does not exist or is not accessible. >&2
endlocal
exit /b 1
)

echo [INFO] Cluster size for %DriveColon%
echo.

:: Use PowerShell for reliable, cross-filesystem cluster size retrieval
powershell -NoProfile -Command ^
"try {" ^
" $vol = Get-Volume -DriveLetter '%DriveLetter%' -ErrorAction Stop;" ^
" $wmiVol = Get-CimInstance Win32_Volume -Filter \"DriveLetter='%DriveColon%'\" -ErrorAction SilentlyContinue;" ^
" $clusterSize = if ($wmiVol) { $wmiVol.BlockSize } else { 'Unknown' };" ^
" Write-Host \" Drive: %DriveColon%\";" ^
" Write-Host \" File System: $($vol.FileSystemType)\";" ^
" Write-Host \" Cluster Size: $clusterSize bytes\";" ^
" if ($clusterSize -is [int] -or $clusterSize -is [long]) {" ^
" $clusterKB = $clusterSize / 1024;" ^
" Write-Host \" ($clusterKB KB)\"" ^
" };" ^
" Write-Host \" Label: $(if ($vol.FileSystemLabel) { $vol.FileSystemLabel } else { '(none)' })\";" ^
" Write-Host \" Total Size: $([math]::Round($vol.Size / 1GB, 1)) GB\";" ^
" Write-Host '';" ^
" if ($clusterSize -eq 4096) {" ^
" Write-Host ' [INFO] 4 KB - Standard default. Good for general-purpose workloads.'" ^
" } elseif ($clusterSize -eq 65536) {" ^
" Write-Host ' [INFO] 64 KB - Optimized for large files and databases.';" ^
" Write-Host ' [INFO] May waste space with many small files.'" ^
" } elseif ($clusterSize -lt 4096) {" ^
" Write-Host ' [INFO] Below standard (512 or 2048 bytes). Uncommon configuration.'" ^
" } elseif ($clusterSize -gt 4096 -and $clusterSize -lt 65536) {" ^
" Write-Host \" [INFO] Non-default cluster size. May have been set intentionally for specific workloads.\"" ^
" }" ^
"} catch {" ^
" Write-Error $_.Exception.Message;" ^
" exit 1" ^
"}"

endlocal
exit /b 0

Sample output:

[INFO] Cluster size for C:

Drive: C:
File System: NTFS
Cluster Size: 4096 bytes
Label: (none)
Total Size: 440.7 GB

[INFO] 4 KB - Standard default. Good for general-purpose workloads.

Why Win32_Volume.BlockSize instead of fsutil:

  • fsutil fsinfo ntfsinfo only works on NTFS volumes. On FAT32 or exFAT drives, it fails with an error.
  • fsutil requires administrator privileges for most queries.
  • Win32_Volume.BlockSize returns the allocation unit size for any file system type (NTFS, FAT32, exFAT, ReFS) and works consistently across Windows versions.
  • On some systems, Get-Volume alone does not expose the cluster size, which is why Win32_Volume from WMI is used as the data source.

Method 2: All-Drive Cluster Size Inventory

This method reports the cluster size for every connected volume in a single table.

@echo off
setlocal

echo [INFO] Cluster size inventory for all volumes:
echo --------------------------------------------------

powershell -NoProfile -Command ^
"$volumes = Get-CimInstance Win32_Volume |" ^
" Where-Object { $_.DriveLetter -and $_.FileSystem };" ^
"if (-not $volumes) {" ^
" Write-Host 'No volumes with drive letters found.';" ^
" exit 0" ^
"};" ^
"$volumes | ForEach-Object {" ^
" $clusterKB = if ($_.BlockSize) { [math]::Round($_.BlockSize / 1024) } else { 'N/A' };" ^
" $totalGB = [math]::Round($_.Capacity / 1GB, 1);" ^
" [PSCustomObject]@{" ^
" Drive = $_.DriveLetter;" ^
" FileSystem = $_.FileSystem;" ^
" 'Cluster (KB)' = $clusterKB;" ^
" 'Cluster (bytes)' = if ($_.BlockSize) { $_.BlockSize } else { 'N/A' };" ^
" Label = if ($_.Label) { $_.Label } else { '(none)' };" ^
" 'Size (GB)' = $totalGB" ^
" }" ^
"} | Sort-Object Drive | Format-Table -AutoSize"

echo --------------------------------------------------

endlocal
exit /b 0

Sample output:

[INFO] Cluster size inventory for all volumes:
--------------------------------------------------
Drive FileSystem Cluster (KB) Cluster (bytes) Label Size (GB)
----- ---------- ------------ --------------- ----- ---------
C: NTFS 4 4096 Windows 476.9
D: NTFS 64 65536 SQLData 931.5
E: exFAT 32 32768 BACKUP_USB 119.2
F: FAT32 4 4096 CAMERA_SD 29.7

What to look for:

  • C: (OS drive) with non-default cluster size: Unusual. Most OS installations use 4 KB. A different size may indicate a special installation process.
  • Database/VM drives with 4 KB clusters: SQL Server and Hyper-V perform best with 64 KB clusters. Consider reformatting these volumes.
  • Large cluster sizes on drives with many small files: Significant space waste. Consider whether the performance benefit justifies the wasted space.
  • Different cluster sizes across similar-purpose drives: Inconsistency may indicate drives were formatted at different times or with different tools.

Method 3: Cluster Size Recommendation Engine

For drive planning and formatting decisions, this method analyzes a drive's current content and suggests the optimal cluster size.

@echo off
setlocal

set "Drive=%~1"

if "%Drive%"=="" (
echo Usage: %~nx0 ^<drive_letter^>
echo.
echo Analyzes drive content and recommends optimal cluster size.
endlocal
exit /b 1
)

set "DriveLetter=%Drive:~0,1%"
set "DriveColon=%DriveLetter%:"

if not exist %DriveColon%\ (
echo [ERROR] Drive %DriveColon% not found. >&2
endlocal
exit /b 1
)

echo [INFO] Analyzing %DriveColon% content for cluster size recommendation...
echo [INFO] This may take a moment on large drives...
echo.

powershell -NoProfile -Command ^
"$drive = '%DriveColon%';" ^
"$files = @(Get-ChildItem -Path $drive -Recurse -File -Force -ErrorAction SilentlyContinue);" ^
"$totalFiles = $files.Count;" ^
"if ($totalFiles -eq 0) { Write-Host 'No files found or access denied.'; exit 0 };" ^
"$avgSize = [math]::Round(($files | Measure-Object Length -Average).Average / 1KB, 1);" ^
"$medianSize = ($files | Sort-Object Length | Select-Object -Index ([math]::Floor($totalFiles / 2))).Length;" ^
"$medianKB = [math]::Round($medianSize / 1KB, 1);" ^
"$smallFiles = @($files | Where-Object { $_.Length -lt 4096 }).Count;" ^
"$largeFiles = @($files | Where-Object { $_.Length -gt 10MB }).Count;" ^
"$smallPct = [math]::Round($smallFiles / $totalFiles * 100, 1);" ^
"$largePct = [math]::Round($largeFiles / $totalFiles * 100, 1);" ^
"Write-Host (' Total files: ' + $totalFiles);" ^
"Write-Host (' Average size: ' + $avgSize + ' KB');" ^
"Write-Host (' Median size: ' + $medianKB + ' KB');" ^
"Write-Host (' Small (<4 KB): ' + $smallFiles + ' (' + $smallPct + '%%)');" ^
"Write-Host (' Large (>10 MB): ' + $largeFiles + ' (' + $largePct + '%%)');" ^
"Write-Host '';" ^
"Write-Host ' Recommendation:';" ^
"if ($largePct -gt 50 -and $smallPct -lt 10) {" ^
" Write-Host ' 64 KB - Drive is dominated by large files.' -ForegroundColor Green;" ^
" Write-Host ' Optimal for sequential I/O performance.'" ^
"} elseif ($smallPct -gt 60) {" ^
" Write-Host ' 4 KB - Drive has many small files.' -ForegroundColor Green;" ^
" Write-Host ' Minimizes wasted space from partial cluster allocation.'" ^
"} else {" ^
" Write-Host ' 4 KB (default) - Mixed file sizes.' -ForegroundColor Green;" ^
" Write-Host ' Best general-purpose balance of space and performance.'" ^
"}"

endlocal
exit /b 0

Sample output:

[INFO] Analyzing D:\ content for cluster size recommendation...
[INFO] This may take a moment on large drives...

Total files: 12458
Average size: 12.4 KB
Median size: 2.1 KB
Small (<4 KB): 7890 (63.3%)
Large (>10 MB): 124 (1.0%)

Recommendation:
4 KB - Drive has many small files.
Minimizes wasted space from partial cluster allocation.

When to use non-default cluster sizes:

WorkloadRecommendedRationale
General purpose / OS drive4 KBBalanced space/performance; NTFS default
SQL Server data files64 KBMicrosoft recommendation; maximizes sequential throughput
Hyper-V virtual disks64 KBReduces metadata overhead for large VHDX operations
Video editing / media64 KBLarge sequential files benefit from fewer allocation units
Source code repositories4 KBMany small files; 64 KB would waste 90%+ space
Log file storage4–16 KBBalance between log file size and write efficiency

Method 4: Fleet-Wide Cluster Size Audit

For auditing cluster sizes across multiple machines, essential for verifying database servers have the recommended 64 KB allocation.

@echo off
setlocal

set "CSVFile=\\Server\Audit\cluster_size_inventory.csv"

if not exist "%CSVFile%" (
echo "Timestamp","Computer","Drive","FileSystem","ClusterBytes","ClusterKB","Label","SizeGB" > "%CSVFile%" 2>nul
)

powershell -NoProfile -Command ^
"$ts = Get-Date -Format 'yyyy-MM-dd HH:mm:ss';" ^
"Get-CimInstance Win32_Volume |" ^
" Where-Object { $_.DriveLetter -and $_.FileSystem } |" ^
" ForEach-Object {" ^
" $clusterKB = if ($_.BlockSize) { [math]::Round($_.BlockSize / 1024) } else { 'N/A' };" ^
" $sizeGB = [math]::Round($_.Capacity / 1GB, 1);" ^
" $label = if ($_.Label) { $_.Label } else { 'none' };" ^
" Write-Output ('\"' + $ts + '\",\"' + $env:COMPUTERNAME + '\",\"' + $_.DriveLetter + '\",\"' + $_.FileSystem + '\",\"' + $_.BlockSize + '\",\"' + $clusterKB + '\",\"' + $label + '\",\"' + $sizeGB + '\"')" ^
" }" >> "%CSVFile%" 2>nul

echo [OK] Cluster size data exported for %COMPUTERNAME%.

endlocal
exit /b 0

What to look for in the fleet CSV:

  • SQL Server machines with 4 KB clusters on data drives: Should be 64 KB per Microsoft best practices. Reformatting may be worth scheduling during a maintenance window.
  • Hyper-V hosts with 4 KB clusters on VM storage: 64 KB improves VHDX performance.
  • Inconsistent cluster sizes across similar-role servers: May indicate non-standardized provisioning processes.

How to Avoid Common Errors

Wrong Way: Assuming 4 KB Is Universal

:: WRONG - not all NTFS volumes use 4 KB
echo Cluster size is 4096 bytes (assumed)

Volumes may have been formatted with non-default cluster sizes. Volumes larger than 16 TB default to larger cluster sizes. Some deployment tools set specific cluster sizes.

Correct Way: Always query the actual cluster size (Methods 1–2). Never assume.

Wrong Way: Using fsutil fsinfo ntfsinfo on Non-NTFS Drives

:: FAILS on FAT32, exFAT, and ReFS volumes
fsutil fsinfo ntfsinfo E:

fsutil fsinfo ntfsinfo is NTFS-specific. It fails on FAT32, exFAT, and ReFS volumes.

Correct Way: Use Win32_Volume.BlockSize (as shown in all methods), which works for any file system type.

Problem: Cannot Change Cluster Size Without Reformatting

Once a volume is formatted, its cluster size is permanently set. There is no resize cluster command.

Solution: To change the cluster size:

  1. Back up all data from the volume.
  2. Format the volume with the new cluster size: format D: /fs:ntfs /a:65536 /q (for 64 KB clusters).
  3. Restore the data.

The /a: parameter of the format command sets the allocation unit size in bytes.

Problem: fsutil Requires Admin Privileges

Most fsutil commands require elevation. Running without admin produces "Error: Access is denied."

Solution: All methods in this guide use PowerShell with Get-CimInstance Win32_Volume, which works without elevation for read-only queries on most systems.

Best Practices and Rules

1. Use 4 KB for General-Purpose Drives

Unless you have a specific workload that benefits from larger clusters (databases, VMs, media editing), the default 4 KB provides the best balance.

2. Use 64 KB for SQL Server and Hyper-V

Microsoft explicitly recommends 64 KB allocation units for SQL Server data volumes and Hyper-V virtual disk storage. This is a well-documented best practice that measurably improves performance.

3. Document the Cluster Size When Formatting

When provisioning new servers, record the cluster size used for each volume. This avoids the need to query it later and ensures consistency across the fleet.

4. Audit Database Servers Regularly

Use Method 4 to verify that database and VM storage volumes maintain the recommended 64 KB cluster size. Drives added or reformatted after initial provisioning may revert to the 4 KB default.

5. Consider Cluster Size Before Large Deployments

Changing the cluster size after the volume is in production requires a backup-format-restore cycle (downtime). Getting it right during initial formatting avoids this disruption.

Conclusions

Querying the cluster size of your volumes provides deep insight into storage performance characteristics and space efficiency. By using Win32_Volume.BlockSize for cross-filesystem compatibility, providing workload-specific recommendations, and auditing cluster sizes across your fleet, you can make informed decisions about formatting strategies and identify volumes that may benefit from optimization. This level of detail is essential for database administrators, virtualization engineers, and anyone who needs to maximize storage performance.