Why deleting doesn't hold
One real workstation, measured 13 days after a cleanup. Same machine, same period — the only difference is whether the location was deleted or relocated.
| What was done | At cleanup | 13 days later | Where the growth landed |
|---|---|---|---|
Deleted only — %LOCALAPPDATA%\Temp | 0 GB | 10.94 GB | back on C: |
Deleted only — NVIDIA DXCache | 0 GB | 0.31 GB | back on C: |
| Relocated — Feishu/Lark data | 3.69 GB | 9.45 GB | D: — 5.76 GB of new cache |
| Relocated — agent session transcripts | 16.18 GB | 16.19 GB | D: |
| Relocated — NuGet + Playwright | 6.71 GB | 6.71 GB | D: |
11.25 GB crawled back onto C: in 13 days — about 0.87 GB/day. A delete-only cleanup is undone in roughly two weeks. Over the same period the relocated set grew 5.32 GB net and not one byte of it went to C:.
That is the whole mechanism: a junction is a filesystem-level redirect, resolved below the application layer. The app opens the same path it always did and never learns that its data now lives on another volume — so its future growth follows the link automatically.
How it compares
To be fair to them: the big Chinese PC suites do use symbolic links to move installed software off C:, and that part works. The differences that matter are what gets moved and what comes attached.
| 360 / Tencent PC suites | CCleaner / Storage Sense | DriveKeeper | |
|---|---|---|---|
| One-click junk cleanup | Yes | Yes | Yes — allowlist, dry-run by default |
| Relocates with junctions | Yes | No | Yes |
| Who decides what moves | The vendor's software list | — | You do — any directory or toolchain |
| Dev toolchain caches via env vars | No | No | NuGet, npm, pip, Playwright, Cargo, Gradle, UE DDC |
| Per-subdirectory safe/unsafe rules | No | No | 30+ apps, extensible |
| Byte-level verify before deleting source | Not documented | N/A | Yes — mismatch aborts |
| Background service, ads, upsells | Yes | Some | None — runs and exits |
| Uninstall | Uninstaller flow | Uninstaller flow | Delete a folder |
| Open source | No | No | MIT |
You point it at anything
There is no vendor list to wait on:
.\Move-AppData.ps1 -Source "$env:APPDATA\SomeAppNobodySupports" -Destination "D:\AppData\SomeApp"
For reference, Windows Storage Sense manages the system drive only, does not touch browser caches, skips app temp files from Teams/Spotify/Discord, and by default runs only once the disk is already nearly full.
What it costs you: about 25 minutes, once
A few minutes of scanning, the deletions, then roughly 11 minutes to copy 29 GB across five relocations, SSD to SSD.
That run recovered 43.7 GB on a 299 GB system drive — 19.0 GB free to 62.7 GB, with zero data lost. Thirteen days later the drive was still at 61.4 GB free. The alternative is re-running a delete-only cleaner every two weeks, indefinitely.
Reclaiming space is easy if you don't mind losing things
This is built the other way round.
- Deletion is allowlist-only. It cannot be pointed at an arbitrary folder — structural, not a policy you have to trust.
- Dry-run by default. Nothing is removed until you pass
-Execute. - Anything a human created or accumulated gets moved, never deleted.
- Byte-level verification before any source is deleted. Bytes and file counts are recounted independently on both sides; a mismatch aborts and restores the original.
The hard part isn't deleting — it's knowing which subdirectory is disposable.
In a Chromium-based app, Service Worker\CacheStorage is disposable and
often over 1.5 GB per profile, but its sibling Service Worker\Database
is not, and Local Storage holds your login token. Folder-level thinking
logs you out.
- Probe for locksRename the directory in place. Success means nothing holds a handle; failure means stop rather than force.
- Copy
robocopy /E /COPY:DAT /DCOPY:DAT. Exit codes below 8 are success. - Recount independentlyTotal bytes and file count on both sides must match exactly. Do not trust the copy tool's summary.
- Delete the sourceOnly now. Until this step the original is fully intact, which is what makes the operation abandonable at any earlier moment.
- Create the junction
mklink /J. From here, future writes follow the link automatically. - Confirm live writesStart the app and verify new files appear on the destination. A silently failed junction looks identical to a working one until you check.
Install
git clone https://github.com/linad3d/drivekeeper.git
Copy-Item -Recurse drivekeeper\skills\windows-disk-cleanup "$env:USERPROFILE\.claude\skills\"
Then describe the problem in plain language:
my C drive is down to 8GB, figure out what's eating it and clean up what's safe
Or run the scripts without Claude
.\Scan-DiskUsage.ps1 -Path C:\ -MinGB 0.3 # see what is actually big
.\Invoke-SafeClean.ps1 # preview - deletes nothing
.\Invoke-SafeClean.ps1 -Category GPU,DevTools -Execute
.\Move-AppData.ps1 -Source "$env:APPDATA\SomeApp" -Destination "D:\AppData\SomeApp"
.\Test-Migration.ps1 -Watch "D:\AppData\SomeApp" # prove the redirect is live
Windows 10/11 · PowerShell 5.1+ · NTFS on both sides · elevation for mklink,
C:\ProgramData and C:\Windows\Temp.
Frequently asked questions
Will the space come back?
%LOCALAPPDATA%\Temp plus 0.31 GB of NVIDIA DXCache) — about 0.87 GB/day, so a delete-only cleanup is undone in roughly two weeks. Over the same period the relocated applications produced 5.32 GB of new data and every byte landed on the destination drive, including 5.76 GB of new Feishu cache.How is this different from 360, Tencent PC Manager, or CCleaner?
How long does it take?
Can it move an app that isn't on the supported list?
Move-AppData.ps1 takes any source and destination — there is no vendor list to wait on. The bundled atlas documents which subdirectories are safe for apps verified firsthand; the relocation machinery itself is generic and works on any directory on an NTFS volume.Will cleaning app caches delete my chat history?
Cache\Cache_Data, Code Cache, GPUCache, the shader caches, and Service Worker\CacheStorage. Login state lives in Local Storage and Cookies; app data lives in IndexedDB and Service Worker\Database. For WeChat and WeCom the skill does not touch the data at all — it points you at the app's own storage setting.Are NTFS junctions safe? Will apps break?
Is it safe to delete the Unreal Engine DerivedDataCache?
.uasset files. Relocating is still preferable, since deleting means recompiling shaders. UE 5.4+ uses Zen Store as the local DDC by default, so relocating %LOCALAPPDATA%\UnrealEngine\Common covers both — stop zenserver.exe first.Does robocopy exit code 1 mean the copy failed?
0 means nothing needed copying, 1 means files were copied successfully, and 8 is the first code indicating a real failure. Test $LASTEXITCODE -lt 8, not $?.Why does my PowerShell script fail with null-reference errors on valid lines?
$null and the script half-runs without erroring. Keep helper .ps1 files pure ASCII, or save as UTF-8 with BOM.Why clean early instead of waiting until the disk is full?
History database into an empty shell and Chrome kept running without recording anything until restarted — the loss was found days later. Treat a nearly full disk as an active data-loss risk.中文说明
清理工具删完就长回来。这个把该映射的映射掉,所以不会。
一个 Claude Code 技能 + 独立可用的 PowerShell 工具包:先把爆满的 C 盘救回来,再用 NTFS 目录连接(junction)和环境变量,把那些反复回涨的目录搬到别的盘。应用还往原来的路径写, 字节落在别处。
实测(同一台机器,清理后第 13 天):只删没搬的地方回涨了 11.25 GB 到 C 盘
(%LOCALAPPDATA%\Temp 10.94 GB + NVIDIA DXCache 0.31 GB),约 0.87 GB/天——
也就是说,一次只删的清理大约两周就白干了。同期做了映射的那批新增 5.32 GB,
没有一个字节进 C 盘,其中光飞书就新增了 5.76 GB 缓存,全落在 D 盘。
和 360 安全卫士 / QQ电脑管家比:平心而论,它们的「C盘搬家」确实也是用符号链接实现的, 这部分没问题。区别在两点——搬什么由谁决定:它们搬的是厂商内置列表里的已安装软件, 而这个是你指哪搬哪,包括 NuGet、npm、pip、Playwright、Cargo、Gradle、虚幻引擎 DDC 这些真正在反复涨的开发者缓存;以及附带了什么:这是个 MIT 开源脚本,跑完就退出, 没有常驻后台、没有广告推广,卸载就是删个文件夹。
要花多久:那次完整跑下来约 25 分钟(扫描几分钟 + 删除 + 约 11 分钟复制 29 GB 完成 5 项迁移),释放 43.7 GB,零数据丢失。一次性投入。