DISM prints one line that splits every fleet in two: Component Store Cleanup Recommended : Yes. Half of us ignore it for three years. The other half wrap /StartComponentCleanup /ResetBase in a remediation script and push it to ten thousand devices on a Tuesday. Both groups are guessing, because almost nobody reads the word doing the work in Microsoft's definition of that field. The word is may.
Here is a decision framework instead. Every number came off one real corporate Windows 11 Enterprise device, 25H2, build 26200.9168, read-only, on 22 and 23 August 2026 — including the moment the automatic cleanup task ran, reported success, and reclaimed nothing at all.
Microsoft defines Component Store Cleanup Recommended as a hint that cleanup may reduce component store overhead — not a measurement of what you would get back. On the lab device Explorer reports 24.81 GB, the actual store is 22.80 GB, and 8.00 GB of that is shared with live Windows via hard links and is not overhead at all. Real overhead is 14.79 GB, and only some of that is reclaimable today because the automatic task honours a documented 30-day grace period. /StartComponentCleanup alone removes superseded components. Adding /ResetBase removes all superseded versions, and Microsoft's warning is blunt: existing update packages cannot be uninstalled afterwards. The automatic task has a documented 1-hour timeout, and on this device its real XML sets StopOnIdleEnd true with RestartOnIdle false — which is exactly why one run on 21 August was killed mid-flight by Event 328, "because computer is no longer idle", and never came back.
The problem: "Cleanup Recommended: Yes" is a hint, not an instruction
Here is the real report from the lab device. Nothing was edited except trimming DISM's progress bar, which prints roughly a hundred lines of ASCII to say "working".
Four numbers, four meanings, and a fifth line recommending cleanup. Most people read the 24.81 GB, read the "Yes", and reach for the biggest hammer available. That reflex is the failure mode, because Microsoft's own definition of the field is deliberately hedged.
Component Store Cleanup Recommended as follows: "This is a component store cleanup recommendation. Cleanup is recommended when performing a cleanup process may reduce the size of the component store overhead." It is a statement that overhead exists and that cleanup could touch some of it. It is not a size, not a prediction, and not a health verdict. A device can sit at "Yes" indefinitely while behaving perfectly.The second failure mode is worse: running /ResetBase across a fleet the week before a bad cumulative update lands. Microsoft states the consequence twice, on two pages. WinSxS cleanup guidance: "All existing update packages can't be uninstalled after this command is completed, but this won't block the uninstallation of future update packages." DISM reference: "Installed Windows updates can't be uninstalled after running /StartComponentCleanup with the /ResetBase option."
/ResetBase deletes the material both of those depend on for everything currently installed. If you are inside a patch window, or you have any KB on the device you might need to roll back, /ResetBase is not a maintenance task. It is a one-way door.Why it happens: eight fields, hard links, and a task that did nothing
The eight report fields, decoded
The report has exactly eight fields and Microsoft documents every one of them. Here they are against what the lab device actually printed.
| Report field | What Microsoft documents it to mean | Lab device value, and how to read it |
|---|---|---|
| Windows Explorer Reported Size of Component Store | "the size of the WinSxS folder if computed by Windows Explorer. This value doesn't factor in the use of hard links within the WinSxS folder." | 24.81 GB — the number in the ticket, and the least useful number in the report |
| Actual Size of Component Store | "factors in hard links within the WinSxS folder. It doesn't exclude files that are shared with Windows by using hard links." | 22.80 GB — real bytes on disk, but still includes live OS files |
| Shared with Windows | "the size of files that are hard linked so that they appear both in the component store and in other locations ... This is included in the actual size, but shouldn't be considered part of the component store overhead." | 8.00 GB — running Windows. Not reclaimable by anything, ever |
| Backups and Disabled Features | "the size of the components that are being kept to respond to failures in newer components or to provide the option of enabling more functionality. It also includes the size of component store metadata and side-by-side components. This is included in the actual size and is part of the component store overhead." | 14.79 GB — your rollback capability, priced in gigabytes |
| Cache and Temporary Data | "the size of files that are used internally by the component store to make component servicing operations faster. This is included in the actual size and is part of the component store overhead." | 0 bytes — already scavenged |
| Date of Last Cleanup | "the date of the most recently completed component store cleanup." | 2026-08-22 13:37:36 — yesterday. Note "completed", not "reclaimed" |
| Number of Reclaimable Packages | "the number of superseded packages on the system that component cleanup can remove." | 21 — a count of packages, not a size |
| Component Store Cleanup Recommended | "a component store cleanup recommendation. Cleanup is recommended when performing a cleanup process may reduce the size of the component store overhead." | Yes — overhead exists. Nothing more is claimed |
Why Explorer overstates by 2.01 GB
The gap between 24.81 and 22.80 is 2.01 GB, and it is not a bug. It is hard links counted more than once.
Microsoft: "there's usually only one copy of the file and the rest of the copies are actually hard links. Some tools, such as the File Explorer, determine the size of directories without taking into account that the contained files might be hard linked." A hard link is two directory entries pointing at one set of blocks. Explorer counts those blocks once per entry; DISM knows the difference.
Which makes the report's arithmetic checkable, and it checks out. Actual size minus shared-with-Windows is 22.80 minus 8.00, or 14.80 GB. Overhead is backups plus cache, or 14.79 GB plus zero. The 0.01 GB is rounding. Two independent paths to the same number is how you know you are reading it right.
Twenty-one reclaimable packages, one day after a successful cleanup
Now the part that makes the "Yes" confusing. The report says the last cleanup completed at 13:37:36 on 22 August, and that 21 packages are still reclaimable. Both are true, and the reason is documented.
Microsoft: "When run automatically, the task will wait at least 30 days after an updated component has been installed before uninstalling the previous versions of the component." That grace period is the whole point. It is the window in which you can still uninstall a bad KB.
The three newest updates here are KB5123304 (19 August), KB5121003 and KB5120708 (both 20 August). On 23 August they are three and four days old, so everything they superseded is deliberately still on disk. The package inventory measured on the same device shows the shape: 199 superseded, 121 installed, 95 staged. Superseded components are the raw material for both cleanup and rollback — the same bytes serving two purposes.
The run that reported success and reclaimed 1.3 MB
This is the part I did not expect to find. The automatic task really did run at 13:37 on 22 August. It really did return success. And it did essentially nothing, for a reason written plainly in CBS.log.
Read the sequence again. CSI compared a store coherency cookie against the cookie from the previous scavenge, found them identical, and skipped the work. CBS then stamped the run as complete, which is what set Date of Last Cleanup to 13:37:36.
So the report field is accurate and also misleading. A cleanup completed. Nothing was cleaned. And the 21 reclaimable packages would not have been touched even if the scavenge had run, because they sit inside the 30-day grace window.
Date of Last Cleanup and a task result of 0 together prove only that the task ran to completion. They do not prove a single byte was reclaimed. On this device they coexist with a 13-second run, a zero-second scavenge, and 1.3 MB of change. If your fleet reporting treats "task succeeded" as "device cleaned", it is measuring the wrong thing.Which binaries actually do this work
Worth knowing, because two of these are not where people assume they are. Every path and version below was read off the lab device.
| Binary | Verified location on the lab device | Role in a cleanup |
|---|---|---|
Dism.exe (10.0.26100.8457) | C:\Windows\System32\ | FileDescription "Dism Image Servicing Utility". The front end you type. It does not do the cleanup itself |
dismapi.dll (10.0.26100.8457) | C:\Windows\System32\ | "DISM API Framework" — the programmatic surface behind the CLI |
DismCore.dll (10.0.26100.8457) | C:\Windows\System32\Dism\ | "DISM Core Framework" — note the Dism subfolder, not System32 itself |
TrustedInstaller.exe (10.0.26100.7019) | C:\Windows\servicing\ | "Windows Modules Installer". Hosts the COM object the scheduled task invokes |
TiWorker.exe (10.0.26100.9156) | versioned WinSxS servicing-stack component directory | "Windows Modules Installer Worker". The process that performs the scavenge |
cbscore.dll (10.0.26100.9156) | same versioned WinSxS servicing-stack directory — not System32 | "Component Based Servicing Core DLL". Named in the real log line "Loaded Servicing Stack ... with Core:" |
wcp.dll (10.0.26100.9156) | same WinSxS servicing-stack directory. Verified absent from System32 | "Windows Componentization Platform Servicing API" — this is CSI. It is the component that decided to skip the scavenge |
COMPONENTS | C:\Windows\System32\config\COMPONENTS | The registry hive CBS loads to read package state. Real log line: "Loading registry hive C:\WINDOWS\System32\config\Components" |
The servicing stack is versioned separately from the OS: this device runs build 26200.9168 on stack 10.0.26100.9156, which is normal. That is why hardcoding a WinSxS path into a script loses. Read the path out of CBS.log instead.
How to verify: a decision path you can actually follow
Nine steps. Every one is read-only. Do not run a cleanup switch until you reach step 9, because steps 1 through 8 are the evidence that tells you which switch, if any, is correct.
- Get the real numbers. Run
Dism.exe /Online /Cleanup-Image /AnalyzeComponentStoreelevated and record all eight fields. If you only log one, logBackups and Disabled Features— the only field that represents recoverable space. - Compute overhead and sanity check it. Overhead is backups plus cache. Confirm it roughly equals actual size minus shared-with-Windows. Disagreement beyond rounding means a truncated or stale report.
- Decide whether the number is worth acting on. Here it is 14.79 GB against 420 GB free: a monitoring note, not an incident. Cleanup earns its risk on constrained disks, not on principle.
- Check the store is healthy first.
/CheckHealthonly reads a flag a previous failed operation set;/ScanHealthactually scans. Never clean up a store you have not confirmed is intact — you will delete the known-good versions a repair would have used. - Look at how old the newest updates are. If the most recent KB landed within 30 days, the automatic task will not remove what it superseded, by design. That is your answer to "why does it still recommend cleanup".
- Ask whether you are inside a rollback window. This is the decision, and it is not a technical question. If a cumulative update landed this month and the fleet is not yet confirmed stable on it, those superseded versions are insurance you are still holding.
- Check whether someone already spent it. Microsoft documents exactly one registry value for this, below.
- Check whether the automatic task is completing. Read the task XML and its history before concluding maintenance is broken. On this device it is not broken; it is being interrupted.
- Only now choose a switch — the scheduled task,
/StartComponentCleanup, or/StartComponentCleanup /ResetBase.
Step 7: the one documented registry value
Microsoft's DISM reference gives exactly one tip here: "To determine when the /ResetBase option was last run, check the LastResetBase_UTC registry entry." Every value in the table shares this parent key.
| Value | Meaning | What to look for |
|---|---|---|
LastResetBase_UTC | Documented. Microsoft: the entry to check "to determine when the /ResetBase option was last run" | Absent on the lab device — /ResetBase has never run here, so the rollback path is intact. Present means someone already spent it. This is your fleet audit query |
Corrupt | Undocumented. Observed as 0 on this healthy device | Use as a fleet comparison signal only. Confirm any suspicion with /ScanHealth, which is the documented scan |
AutoRepairNeeded | Undocumented. Observed as 0 | Same discipline: treat a non-zero as a prompt to scan, never as a diagnosis in its own right |
LifetimeTimesSuccessfullyRepaired | Undocumented. Observed as 5 on this device | A store with a repair history is a reason to be more conservative about /ResetBase, not less |
LastModified_UTC | Undocumented. Observed as the string 2026/08/21/20:46:05 | Note the format: slash-delimited string, not a FILETIME. Scripts that cast it to a date will throw. Read it as text |
NextExecutionSequence | Undocumented. Observed as 434 | Monotonic counter. Only meaningful as a delta between two reads of the same device |
LastResetBase_UTC across the estate before you plan any cleanup rollout. Devices where it already exists have no rollback path for anything installed before that timestamp, which changes your remediation options for a bad KB on exactly those machines. It is a two-line read and it is the single most useful thing in this whole registry key.Step 8: read the task, then read its history
Here is the real definition of the automatic cleanup task, exported read-only from the lab device.
Three settings in there decide whether your fleet ever finishes a cleanup.
ExecutionTimeLimit is PT1H — the documented timeout made visible: "If you choose to run this task, the task will have a 1 hour timeout and may not completely clean up all files." DisallowStartIfOnBatteries and StopIfGoingOnBatteries are both true, matching the documented default and the rule that maintenance runs only "when the machine is idle and on AC power". A laptop that lives on battery never cleans up.
Then the pair that matters most. StopOnIdleEnd is true and RestartOnIdle is false. Microsoft's rule is explicit: "To terminate and restart a task, both properties and elements must be set to True." Only one is. So the task terminates when the user comes back, and does not resume when the machine goes idle again.
The event log proof that this actually happens
All events below are from the channel Microsoft-Windows-TaskScheduler/Operational, which is enabled by default and held 16,915 records on this device. These are the real entries for the cleanup task.
| Event ID | Message (as logged on the lab device) | What it tells you |
|---|---|---|
| 100 | Task Scheduler started "{GUID}" instance of the "\Microsoft\Windows\Servicing\StartComponentCleanup" task for user "NT AUTHORITY\SYSTEM". | Automatic Maintenance judged the device idle and on AC. This timestamp is the only reliable start time |
| 200 | Task Scheduler launched action "Component Based Servicing Session" in instance "{GUID}" of task "\Microsoft\Windows\Servicing\StartComponentCleanup". | The action name is the COM object, confirming there is no executable to trace |
| 328 | Task Scheduler stopped instance "{0fe1ce60-...}" of task "\Microsoft\Windows\Servicing\StartComponentCleanup" because computer is no longer idle. | The one to hunt for. The run was killed by user activity. With RestartOnIdle false it will not resume |
| 201 | Task Scheduler successfully completed task "\Microsoft\Windows\Servicing\StartComponentCleanup", instance "{GUID}", action "Component Based Servicing Session" with return code 0. | The COM handler returned 0. That is all. It is not evidence anything was reclaimed |
| 102 | Task Scheduler successfully finished "{GUID}" instance of the "\Microsoft\Windows\Servicing\StartComponentCleanup" task for user "NT AUTHORITY\SYSTEM". | Instance teardown. Pair 100 with 102 for true wall-clock duration — 15 seconds on 22 August |
| 129 | Task Scheduler launch task "{path}", instance "{exe}" with process ID {pid}. | Present 501 times in this log for other tasks, and never for this one. Corroborates the COM-handler design |
Now put the two runs side by side. Within the log retention on this device, the cleanup task attempted twice.
Two attempts, two nights running. One terminated at six minutes because somebody touched the keyboard. One completed in fifteen seconds having deliberately skipped the work. Scale that to a laptop estate and the mystery of the permanent "Cleanup Recommended: Yes" evaporates.
P14D on this device, only fires when the task keeps failing to complete — not when it completes without achieving anything.The fix: what each switch buys and what /ResetBase costs
There are three routes, and they are not interchangeable. Microsoft's full syntax shows how they nest: /Cleanup-Image {... | /StartComponentCleanup [/ResetBase [/Defer]] | /AnalyzeComponentStore | ...}.
| Route | What Microsoft documents it to do | What it costs you |
|---|---|---|
The scheduled taskschtasks.exe /Run /TN "\Microsoft\Windows\Servicing\StartComponentCleanup" | "automatically cleans up components when the system isn't in use". Waits "at least 30 days after an updated component has been installed before uninstalling the previous versions" | A documented 1-hour timeout, and it "may not completely clean up all files". Costs you nothing in rollback capability. This is the safe default |
Dism.exe /online /Cleanup-Image /StartComponentCleanup | "Cleans up the superseded components and reduces the size of the component store." Similar to the task "except previous versions of updated components will be immediately deleted (without a 30 day grace period) and you will not have a 1-hour timeout limitation" | You forfeit the 30-day grace window for whatever it removes on this run. Updates installed before it still uninstall; you have simply thinned the older layers |
Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase | "removes all superseded versions of every component in the component store". Resets the base of superseded components, "which can further reduce the component store size" | The one-way door. "All existing update packages can't be uninstalled after this command is completed, but this won't block the uninstallation of future update packages" |
Read the /ResetBase cost precisely, because the precision is the point. It is not "you can never uninstall updates again" — future packages are unaffected. What you lose is the ability to uninstall everything currently installed, permanently, on that device.
So the cost is entirely a function of timing. Run it the day before a bad cumulative update ships and you have lost nothing. Run it the day after you deployed one and your rollback plan for that KB is gone, on every device the script touched.
/Defer can be combined with /ResetBase, but Microsoft is unusually specific about scope: available "Beginning with Windows 10, version 1607, you can specify /Defer with /ResetBase, but you should only use /Defer as an option in the factory where DISM /Resetbase requires more than 30 minutes to complete." It defers long-running cleanup to the next automatic maintenance. It is an imaging tool, not a fleet tool. Do not put it in a remediation script.The decision, stated plainly
Run nothing, and just monitor, when overhead is a small fraction of free space — 14.79 GB against 420 GB here. There is no case for spending risk.
Run the scheduled task when you want space back and want to keep every rollback option. It respects the 30-day window, which is exactly the protection you want mid patch cycle. Its weakness is the one-hour timeout and the idle interruption, so trigger it explicitly rather than hoping maintenance gets there.
Run /StartComponentCleanup without /ResetBase when a device is genuinely disk-constrained and needs more than the task will give. You skip the grace period but keep uninstall capability for installed updates.
Run /ResetBase in only two situations. On a reference image you are about to capture, where nothing has been in production so nothing is worth rolling back. Or on a specific device in a real disk emergency, where you have consciously decided free space now beats rollback later — and written that decision down.
/ResetBase for cases where you have actually reasoned about the trade.Proof it worked: the evidence set to capture on both sides
I deliberately did not run /ResetBase here, so there are no after-numbers and I am not going to invent any. What I can give you is the measurement protocol and the real before-state. Capture these six things before you touch anything, and the same six afterwards.
Item 6 is the one nobody checks and the one that settles arguments. A cleanup reporting success with a zero-second scavenge did not clean anything, and re-running the task will not change that until the store itself changes.
After a real cleanup, success looks like this: Backups and Disabled Features is smaller, Number of Reclaimable Packages is lower, and CBS.log shows a scavenge with a non-zero duration and a meaningful used space change. If you ran /ResetBase, LastResetBase_UTC now exists — your permanent, machine-readable record that rollback for everything installed before that timestamp is gone.
And if Cleanup Recommended still says Yes afterwards, that is not a failure. It says overhead remains. On a device patched three days ago, protected by a 30-day grace period, that is the system working correctly.
References
- Determine the Actual Size of the WinSxS Folder - the
/AnalyzeComponentStorecommand, the definitions of all eight report fields, and the overhead formula. - Clean Up the WinSxS Folder - the
StartComponentCleanuptask path, the 30-day grace period, the 1-hour timeout, the/ResetBaseuninstall warning, and the recommendation not to disable component cleanup. - DISM Operating System Package Servicing Command-Line Options - the full
/Cleanup-Imagesyntax, the/StartComponentCleanupand/ResetBasedescriptions, the/Deferfactory-only caveat, and theLastResetBase_UTCregistry tip. - Manage the Component Store - what the component store is for, including "Uninstalling problematic updates", and the hard link worked example.
- Automatic maintenance (Task Scheduler) - maintenance tasks run only when "idle and on AC power", task starvation, suspension on user return, and the rule that a completed attempt counts as successful even with a failure code.
- Task idle conditions - the definition of idle, the
DisallowStartIfOnBatteriesdefault, and the rule thatStopOnIdleEndandRestartOnIdlemust both be true for a task to terminate and restart. - MaintenanceSettings element - what
PeriodandDeadlinemean, and when the scheduler escalates to emergency Automatic maintenance.
All device values here were read from a single corporate Windows 11 Enterprise 25H2 device, build 26200.9168, servicing stack 10.0.26100.9156, on 22 and 23 August 2026. Every command shown is read-only, and no cleanup switch was executed — which is why there are no after-numbers. Validate against your own pilot ring before applying any of this to a fleet.