Chris Lorenzo

homelab and infrastructure notes · stayz3ro

entry-17

Where 875GB of disk actually went, and the backup that came out of it

A 953GB drive down to 88GB free, traced to a bloated WSL vhdx, Docker layer cache, and an orphaned OneDrive folder that was syncing to nothing. Fixed with sparse VHD mode and a distro cleanup, then backed up for real with rclone to Proton Drive and OneDrive.

revisions rev. 1 first set 2026-10-23 last revised 2026-10-23 7 min read

The Windows side of my machine had 88GB free out of 953GB, and I could not say why. Games, probably. That was the theory. The point of this session was to stop theorizing and find out, and the answer turned out to be more interesting than “games”: a 100GB WSL virtual disk holding maybe 10GB of actual data, 20GB of Docker cache, and a 51GB OneDrive folder that was not syncing to anything at all.

This is the whole arc: the disk investigation, the fixes, and the backup system that came out of it, because the orphaned folder turned out to be the biggest collection of unprotected data on the machine.

Step 1: find the space before freeing it

PowerShell’s folder sizes, top down. No guessing:

Get-ChildItem C:\Users\<user> -Directory -Force -ErrorAction SilentlyContinue | ForEach-Object {
  $size = (Get-ChildItem $_.FullName -Recurse -File -Force -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum / 1GB
  [PSCustomObject]@{ Folder = $_.Name; SizeGB = [math]::Round($size,1) }
} | Sort-Object SizeGB -Descending

The full C:\ breakdown put ~482GB in Program Files, which is games and launchers, reinstallable and not a backup concern. The interesting number was in my user profile: AppData at 165GB, dwarfing everything else, with OneDrive at 50GB and Downloads at 49GB behind it. AppData is where nobody looks, so that is where I looked.

WhatSizeVerdict
AppData\Local\wsl103.5GBvhdx bloat, fixable
AppData\Local\Docker~20GBDocker Desktop’s own distro + cache
Program Files (both)~482GBgames/apps, reinstallable
OneDrive50GBorphaned, see below
Downloads~49GBmostly installers and junk
Everything personal, total~6GBthe actual backup problem

The vhdx ratchet

WSL2 stores each distro as an ext4.vhdx file on the Windows side. The file grows as you install packages, pull Docker layers, and build things. It does not grow back down when you delete things inside WSL. Every removed image layer and cleared cache freed space inside the container that Windows could never see again. The ratchet only turns one way, so mine had climbed to 103.5GB. Everything inventoried inside WSL, including every repo, tool cache, and config directory, added up to roughly 10GB. Ninety-plus GB of the file was trapped emptiness.

The listing also showed there were three of them: my main Debian distro at 72GB, Ubuntu at 12.9GB, and kali-linux at 18.5GB, untouched for a week. Docker Desktop turned out to be a fourth, separate vhdx under its own path entirely.

Three fixes, in increasing order of commitment:

  1. docker system prune -a --volumes inside WSL. Safe to run live, nothing in use gets touched. It freed 3.89GB immediately and left the running noc-restyle stack alone.
  2. sparseVhd=true under [wsl2] in .wslconfig. This is the real fix for the ratchet: with sparse mode on, the vhdx actually returns blocks to Windows as things are deleted, instead of just freeing space inside the file. Two caveats I confirmed rather than assumed: it needs a reasonably recent WSL release (wsl --version, wsl --update if stale; otherwise the setting is silently ignored), and it only stops future growth. It does not shrink what is already there.
  3. Unregister the unused distros and compact the main one. The 18.5GB Kali and 12.9GB Ubuntu distros were sitting idle, and wsl --unregister <name> deletes a distro’s vhdx outright, no compaction needed. The Debian one gets the one-time wsl --shutdown plus diskpart → select vdisk file=... → compact vdisk treatment, queued for a restart window since the file cannot be compacted while mounted.

The lesson from the vhdx numbers: the one file nobody thinks to check was bigger than every piece of personal data on the machine combined.

The orphaned OneDrive

The C:\Users\<user>\OneDrive folder was 51GB, structured like a full user profile from 2023, with its own Desktop, Documents, Pictures, OLD_PROJECT_BACKUPS, dating back years. Meanwhile the OneDrive account actually signed in on this machine had a fresh, empty sync folder. The 51GB was left over from a previous account sign-in: files that look backed up, named after a backup service, syncing to nothing. Local disk only. If the drive died, they were gone.

That is the quiet failure mode of cloud folders. A folder named “OneDrive” reads as safe. The only way to know is to check what the client is actually signed into and compare.

Peeking inside before moving anything turned up the session’s most important subdirectory: HDD_backup_06_06_26, a 22GB archive from a previous machine, containing:

  • ~20.5GB of macOS installer ISOs and DMGs. They are reinstallable, not irreplaceable, skip.
  • ~2.1GB of real 3D-printing work: STL files, GCODE, printer profiles.
  • A small set of genuinely sensitive files: two copies of a BitLocker recovery key PDF, a PGP secret key, a FORScan license. Those are not “nice to have” files, and they went somewhere with zero-access encryption, not general-purpose cloud storage.

The backup map

With the survey done, everything on the machine sorted into four buckets:

DestinationContents
Proton Pass (attachments)Six SSH keys, BitLocker recovery PDFs, PGP secret key
Proton Drive (E2E)Obsidian vault, which holds personal notes with no other copy
OneDrive3DP files, chris pc backup, Divine Tribe (~5.5GB), ten resume versions, two Omada router config backups, WhatsApp export
Skipped on purposeEvery ISO, AppData caches, anything already git-backed on GitHub

The sensitive tier went to Proton Pass first, before any of this, so the keys existed in two places before the bulk transfer started.

rclone, two remotes

rclone config in the WSL terminal, not in an agent chat, so no credential ever transits a transcript:

  1. n → onedrive → type onedrive → browser auth. WSL2 forwards localhost, so if rclone prints a URL instead of opening a browser, pasting it into any Windows browser just works.
  2. n again → protondrive → type protondrive → credentials entered directly at the prompt.

rclone listremotes confirms both. Then rclone copy, small stuff first:

rclone copy "/mnt/c/Users/<user>/OneDrive/Documents" onedrive:Backup/resumes-and-misc --max-depth 1 --include "*.pdf" -P
rclone copy "/mnt/c/Users/<user>/Downloads/WhatsApp Unknown 2026-09-06 at 10.38.59.zip" onedrive:Backup/whatsapp/ -P
rclone copy ~/obsidian-vaults protondrive:Backup/obsidian-vault -P

Then the ~5.5GB of 3D-printing content in the background, with --log-file per job so completion is verifiable rather than assumed. Status as of this draft:

RemoteFolderObjectsSize
onedriveBackup/3DP-Files1,1992.00 GiB
onedriveBackup/resumes-and-misc11
onedriveBackup/router-configs2
onedriveBackup/whatsapp1
onedriveBackup/Divine-Tribe38018.2 MiB
onedriveBackup/chris-pc-backup1,2082.02 GiB
protondriveBackup/obsidian-vaultvault tree, confirmed

Not done yet

Honest ledger, same rule as the last backup post: a copy that has never been restored is a theory.

  • All planned copies have finished. Nothing is in flight as I write this.
  • No restore test has been run against either remote. Until something is pulled back down and compared, this is unverified backup, not verified backup.
  • The vhdx compaction is queued behind a WSL restart window.
  • Scheduling is manual so far; the copy commands are one-shot, not cron.

The restore test is the next step before this gets called a system.

Closing note

Three things worth repeating. Check the file nobody thinks to check: the WSL vhdx was bigger than all my real data combined, and it got there by never shrinking. Cloud folder names lie: “OneDrive” on disk means nothing about what is syncing, and the only proof is the client’s sign-in state. And encrypt by sensitivity tier: BitLocker keys and PGP secrets belong somewhere with zero-access encryption, resumes can go anywhere, and reinstallable ISOs go nowhere at all.

The machine went from “88GB free, no backups, unknown contents” to “every irreplaceable file identified, sorted by tier, and mostly in the cloud” in one session. The remaining work is proving the restores.