Share via

Storage Spaces SSD (write cache) tier footprint not increasing during small/big random writes to HDD parity virtual disk

Stan Odd 20 Reputation points
2026-06-20T19:58:43.6333333+00:00

Hello,

I'm trying to build a Storage Spaces array on Windows 11 Pro for Workstations - 8 HDDs (dual parity) and 4 enterprise SAS SSDs intended as a write cache/fast tier.

I've tried two configurations:

  1. Tiered pool — SSDs as Auto-Select with a separate SSD mirror tier + HDD parity tier
  2. Non-tiered — SSDs set to Usage: Journal with -WriteCacheSize on the virtual disk

In both cases I can't confirm the SSDs are actually being used. I'm testing with small (64KB) random file writes and big files writes, and watching WriteCacheUsedSize and FootprintOnPool on the tiers, but values stay at 0 or don't change.

If I understand it correctly Enable-StorageBusCache and S2D features are Server-only and don't apply here.

Could anyone confirm: which configuration (tiered vs Journal or Both together) actually works for SSD caching on desktop Windows, and what's the correct way to verify it's functioning?

Are there any mistakes in how I create it and/or test it?

Thanks

COMMON SETUP

Get-PhysicalDisk -CanPool $True | Select FriendlyName, MediaType, @{N="SizeGB";E={[math]::Round($_.Size/1GB,1)}} | Format-Table -AutoSize
$HDDNumbers = @(0,1,2,3,4,5,6,7)
$SSDNumbers = @(12,13,14,15)
$HDDPhysicalDisks = Get-PhysicalDisk | Where-Object { ($_ | Get-Disk -ErrorAction SilentlyContinue).Number -in $HDDNumbers }
$SSDPhysicalDisks = Get-PhysicalDisk | Where-Object { ($_ | Get-Disk -ErrorAction SilentlyContinue).Number -in $SSDNumbers }
$AllPhysicalDisks = $HDDPhysicalDisks + $SSDPhysicalDisks
foreach ($disk in $HDDPhysicalDisks) { Set-PhysicalDisk -UniqueId $disk.UniqueId -MediaType HDD }
foreach ($disk in $SSDPhysicalDisks) { Set-PhysicalDisk -UniqueId $disk.UniqueId -MediaType SSD }
New-StoragePool -FriendlyName "MainPool" -StorageSubsystemFriendlyName "Windows Storage*" -PhysicalDisks $AllPhysicalDisks -ProvisioningTypeDefault Fixed

OPTION 1 — Tiered (SSDs as hot tier, Auto-Select)

New-StorageTier -StoragePoolFriendlyName "MainPool" -FriendlyName "SSD_Tier" -MediaType SSD -ResiliencySettingName Mirror -NumberOfColumns 2
New-StorageTier -StoragePoolFriendlyName "MainPool" -FriendlyName "HDD_Tier" -MediaType HDD -ResiliencySettingName Parity -PhysicalDiskRedundancy 2 -NumberOfColumns 6 -Interleave 16384
$VD = New-VirtualDisk -StoragePoolFriendlyName "MainPool" -FriendlyName "StorageArray" -StorageTiers (Get-StorageTier -FriendlyName "SSD_Tier","HDD_Tier") -StorageTierSizes @(150GB, 20TB) -FaultDomainAwareness PhysicalDisk -ColumnIsolation PhysicalDisk -ProvisioningType Thin
$Disk = Get-Disk -VirtualDisk $VD
Initialize-Disk -Number $Disk.Number -PartitionStyle GPT
$Partition = New-Partition -DiskNumber $Disk.Number -UseMaximumSize -AssignDriveLetter
Format-Volume -Partition $Partition -FileSystem NTFS -AllocationUnitSize 65536 -NewFileSystemLabel "BU" -Confirm:$false

OPTION 2 — Non-tiered (SSDs as Journal/write cache)

Get-StoragePool -FriendlyName "MainPool" | Get-PhysicalDisk | Where-Object {$_.MediaType -eq "SSD"} | Set-PhysicalDisk -Usage Journal
New-StorageTier -StoragePoolFriendlyName "MainPool" -FriendlyName "HDD_Tier" -MediaType HDD -ResiliencySettingName Parity -PhysicalDiskRedundancy 2 -NumberOfColumns 6 -Interleave 16384
$VD = New-VirtualDisk -StoragePoolFriendlyName "MainPool" -FriendlyName "StorageArray" -StorageTiers (Get-StorageTier -FriendlyName "HDD_Tier") -StorageTierSizes @(20TB) -FaultDomainAwareness PhysicalDisk -ColumnIsolation PhysicalDisk -WriteCacheSize 150GB -ProvisioningType Thin
$Disk = Get-Disk -VirtualDisk $VD
Initialize-Disk -Number $Disk.Number -PartitionStyle GPT
$Partition = New-Partition -DiskNumber $Disk.Number -UseMaximumSize -AssignDriveLetter
Format-Volume -Partition $Partition -FileSystem NTFS -AllocationUnitSize 65536 -NewFileSystemLabel "BU" -Confirm:$false

TEST

  1. List tiers in array
Get-StorageTier | Select FriendlyName, ResiliencySettingName, MediaType, NumberOfColumns, Interleave, PhysicalDiskRedundancy | Format-Table -AutoSize
  1. List tiers and show if Auto-Select or Journal
Get-StoragePool -FriendlyName "MainPool" | Get-PhysicalDisk | Select FriendlyName, MediaType, Usage | Sort-Object MediaType | Format-Table -AutoSize
  1. How much space does cache/SSD tier have
Get-StorageTier | Where-Object {$_.MediaType -eq "SSD"} | Select FriendlyName, @{N="SizeGB";E={[math]::Round($_.Size/1GB,1)}}, @{N="FootprintGB";E={[math]::Round($_.FootprintOnPool/1GB,2)}} | Format-Table -AutoSize
  1. Test that cache is working (during small random writes), the kind that actually use cache (tier footprint)
while($true) { Get-StorageTier | Where-Object {$_.FriendlyName -match "StorageArray"} | Select FriendlyName, @{N="FootprintGB";E={[math]::Round($_.FootprintOnPool/1GB,2)}}; Start-Sleep 3; Write-Host "---" }
  1. How free space changes on SSDs during write (during small/big random writes)(allocation per individual physical SSD disk)
while($true) { Get-StoragePool -FriendlyName "MainPool" | Get-PhysicalDisk | Where-Object {$_.MediaType -eq "SSD"} | Select FriendlyName, @{N="AllocGB";E={[math]::Round($_.AllocatedSize/1GB,2)}}; Start-Sleep 3; Write-Host "---" }
Windows for home | Windows 11 | Files, folders, and storage
0 comments No comments

Answer accepted by question author

Marcin Policht 93,120 Reputation points MVP Volunteer Moderator
2026-06-20T20:07:39.33+00:00

In short, on Windows 11 Pro for Workstations, neither of the two approaches you’re trying gives you a reliably observable “SSD cache tier” in the way Storage Spaces Direct (S2D) does on Windows Server. What you’re seeing (FootprintOnPool staying at 0, WriteCacheUsedSize not moving) is consistent with the client Storage Spaces stack not behaving like a true write-back caching system with SSD consumption counters.

There are three separate mechanisms that often get conflated and it looks like your configs are mixing them in a way that makes verification impractical.

Tiered storage (StorageTier + New-VirtualDisk -StorageTiers) is not a cache. It is placement-based allocation. Data is written into tiers based on slab allocation decisions, not continuously promoted/demoted like S2D. On Windows 11, tier usage is often static after initial allocation, so small random writes may not show any “movement” in SSD footprint counters because nothing is being re-tiered at runtime. Once space is allocated, it tends to stay allocated unless you force optimization.

  • Journal / Usage - Journal is not a general write cache, but rather a metadata journal designed to improve resiliency and reduce write amplification during metadata operations, not to absorb bulk file writes. So your SSDs can be “working” while showing almost no visible capacity change or write-cache metrics moving.

WriteCacheSize on a virtual disk in client Storage Spaces is also not a true persistent SSD cache layer. It is a hint for system write-back buffering, and its behavior is heavily dependent on workload, idle time, and flush policies. It often won’t show measurable SSD consumption the way you expect from S2D cache devices.

The key issue is expecting Windows 11 Storage Spaces to behave like Storage Spaces Direct with an explicit cache device model. That model (HDD + SSD cache devices with write-back + write-through + hot/cold tiers) is a Server feature and is tied to S2D’s clustered storage stack. AFAIK, the proper cache tiering logic is not present in client SKU Storage Spaces.

Regarding tiered vs journal vs both - on Windows 11, only tiering is meaningfully “real,” but it is not dynamic caching, and journal is not a usable performance tier. Combining them does not create a hybrid cache system - it creates two independent and mostly non-interacting mechanisms.

In your testing, small random writes may be absorbed by NTFS cache (system memory), not Storage Spaces. SSD tier allocation happens at provisioning/optimization time, not per-write. FootprintOnPool is not a real-time cache usage metric in client Storage Spaces. Write-back caching may be too small or flushed too quickly to observe. If you want to verify what is actually happening, the only reliable signals on Windows 11 are indirect.

Check actual physical disk I/O counters per SSD using Performance Monitor (Avg. Disk sec/Write, Disk Writes/sec). If SSDs are involved, you will see I/O even if Storage Spaces counters don’t move.

Force tier optimization and then inspect allocation rather than runtime footprint. Client Storage Spaces often only commits tier placement during optimization cycles, not continuously.

Check whether NTFS is absorbing writes first by comparing write rates at volume vs physical disk level. If volume writes are high but SSD/HDD disks show nothing, you are seeing OS-level caching, not Storage Spaces caching.

So unfortunately what you are trying to build (true SSD write cache in front of HDD parity using Storage Spaces on Windows 11) is not truly supported in a measurable way. It will likely behave either like static tiered allocation or like passive journal acceleration, but not like S2D-style caching with visible SSD footprint movement under workload.

You'd effectively need to use Windows Server with S2D, a hardware RAID controller with write-back cache, or a filesystem-level cache layer...


If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

hth

Marcin

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.