Reclaiming 50-100 GB: The Complete Disk Space Cleanup Guide for .NET, Game & Desktop Developers
Every software and game developer on Windows eventually faces the dreaded morning: you boot up your workstation, open your IDE, and suddenly Windows flashes a warning—your system drive has under 2 GB of free space left out of a 1 TB NVMe SSD.
You haven't downloaded massive movie files. You haven't installed new 100 GB games. What happened?
As an indie game and cross-platform desktop developer working with .NET 8/9, MonoGame, Android / Mobile, and Windows Application Packaging (MSIX/WAP for Microsoft Store), I recently investigated this silent SSD crisis. Within minutes of running an automated inspection across my project repositories, I discovered that over 68 GB was being occupied by purely disposable build artifacts, obsolete store packaging bundles, and package caches.
In this guide, we break down the architectural reasons why modern developer toolchains consume monstrous amounts of storage, explain why purging these targets is 100% safe, and provide an automated, copy-pasteable PowerShell and Batch tool that you can drop into any project workspace to instantly reclaim tens of gigabytes.
1. The Anatomy of Developer Disk Bloat
Where does all the storage go? When building cross-platform solutions that target Desktop, Mobile (Android), and Microsoft Store, modern compilers and packaging toolchains duplicate assets and intermediate binaries at every step.
flowchart TD
subgraph "Your Project Workspace"
Code["Source Code (.cs, .xaml, .json)\n(Protected - A few MBs)"]
Assets["Raw Assets (PNG, OGG, Shaders)\n(Protected)"]
Git[".git History\n(Protected)"]
BinObj["bin & obj Directories\n(Intermediate DLLs, symbols, copies)\n[30 - 60 GB]"]
AppPackages["WAP / MSIX AppPackages\n(Historical .msixbundle, .msixupload)\n[5 - 20 GB]"]
end
subgraph "System & Global Caches"
NuGet["%USERPROFILE%\\.nuget\\packages\n(Global Package Cache)\n[10 - 20 GB]"]
Temp["%LOCALAPPDATA%\\Temp\n(Compiler scratch, unpack logs)\n[3 - 10 GB]"]
end
style BinObj fill:#ff6b6b,stroke:#c92a2a,stroke-width:2px,color:#fff
style AppPackages fill:#ff6b6b,stroke:#c92a2a,stroke-width:2px,color:#fff
style NuGet fill:#ff922b,stroke:#d9480f,stroke-width:2px,color:#fff
style Temp fill:#ff922b,stroke:#d9480f,stroke-width:2px,color:#fff
Culprit A: bin and obj Directories (30 - 60+ GB)
Every C# project generates two folders during compilation:
obj/(Intermediate Output): Stores incremental compilation states, generated source files (Source Generators), and platform-specific packaging intermediates. In multi-target projects (e.g., targetingnet9.0-windows10.0andnet9.0-android), the Android intermediate outputs alone can balloon into 3 to 6 GB per project.bin/(Binary Output): Contains final assemblies, runtime dependencies, and all asset files copied via<CopyToOutputDirectory>. If your solution has 10 projects referencing a common 500 MB game content directory, that content is copied 10 times, wasting 5 GB for a single solution!
Culprit B: Microsoft Store AppPackages (5 - 20+ GB)
If you publish desktop games or apps to the Microsoft Store using the Windows Application Packaging (WAP) project, Visual Studio generates a dedicated AppPackages directory.
- Every release creates a full
.msixbundle, a.msixupload(containing full unstripped binaries and PDB symbols for crash reporting), and standalone test installation folders. - A single release package often weighs between 800 MB and 2.5 GB. If you build 10 test versions or iterative patches, Visual Studio never auto-deletes the older versions. They linger indefinitely on your disk.
Culprit C: Global NuGet Package Cache (10 - 20+ GB)
Located at %USERPROFILE%\.nuget\packages, this directory caches every single version of every NuGet package ever downloaded on your machine. If a library updates from version 12.0.1 to 12.0.2, the old version stays cached forever unless manually purged.
Culprit D: Windows User Temp Files (3 - 10 GB)
During build processes, packaging, and asset compression, Visual Studio and MSBuild extract toolchains and temp files into %LOCALAPPDATA%\Temp. Over months of development, thousands of orphaned scratch files pile up.
2. The Safety Guarantee: Why Purging is 100% Risk-Free
Developers are rightfully cautious about deleting files. Here is the ironclad rule of what is safe and what is protected:
| Protected (Never Touched) | Safe to Purge (100% Disposable) |
|---|---|
Source Code: .cs, .xaml, .cpp, .h, .ts, .json |
Intermediate compiler object files (obj/) |
Solution & Project Definitions: .sln, .csproj, .wapproj |
Compiled assemblies and copied binaries (bin/) |
Git Repositories: .git/ folder, commit trees, branches |
Historical Microsoft Store release bundles (AppPackages/) |
Raw Assets: Textures (.png), Audio (.ogg, .wav), Shaders |
Global downloaded NuGet packages (.nuget\packages) |
Certificates & Store Bindings: .pfx, StoreAssociation.xml |
Windows temporary scratch files (%LOCALAPPDATA%\Temp) |
What happens when you reopen Visual Studio?
When you open your project and press Build or Rebuild, Visual Studio and the .NET SDK automatically recreate theobj/andbin/folders from your source code. NuGet automatically downloads any missing packages duringRestore. You lose zero progress and zero settings.
3. The Automated Solution: One-Click Cleanup Script
Instead of manually digging through hundreds of folders, we created a lightweight, self-contained PowerShell tool and a companion Batch launcher.
Features:
- Drive Root Guard: Hard-coded protection that strictly prevents accidentally targeting system root drives (such as
C:\). - Scan-Only Mode: Previews exactly how many gigabytes will be freed without deleting anything.
- Safety Prompt: Clearly reminds the user of what is being cleaned and requests explicit confirmation.
- Graceful File Locking: Skips any file currently locked by an active process (such as a running IDE) without crashing.
The PowerShell Engine (Clean-DevDiskSpace.ps1)
Save this script inside a tools folder in your workspace (e.g., _tools/Clean-DevDiskSpace.ps1 or scripts/Clean-DevDiskSpace.ps1):
<#
.SYNOPSIS
Universal Developer Disk Space Cleanup Tool.
.DESCRIPTION
Scans and safely purges temporary build artifacts (bin/obj), Microsoft Store
packaging output (AppPackages), Windows Temp files, and local NuGet caches.
Source code, git tracking, assets, and project definitions are 100% protected.
#>
[CmdletBinding()]
param (
[switch]$Force,
[switch]$ScanOnly,
[switch]$SkipNuget,
[switch]$SkipTemp,
[string]$RootPath = ""
)
# Robust workspace root resolution
if ([string]::IsNullOrWhiteSpace($RootPath)) {
if ($PSScriptRoot) {
$RootPath = (Join-Path $PSScriptRoot "..")
} else {
$RootPath = Get-Location
}
}
$resolvedRoot = (Resolve-Path $RootPath -ErrorAction SilentlyContinue).Path
# Safety Guard: Never allow running on root drive
if ([string]::IsNullOrWhiteSpace($resolvedRoot) -or $resolvedRoot -in @("C:\", "C:", "\", "/")) {
Write-Host "SAFETY ABORT: Target path is empty or a root drive! Aborting operation." -ForegroundColor Red
exit 1
}
$Host.UI.RawUI.WindowTitle = "Developer Workspace Disk Cleanup"
Write-Host "================================================================================" -ForegroundColor Cyan
Write-Host " DEVELOPER WORKSPACE DISK CLEANUP TOOL " -ForegroundColor Cyan
Write-Host "================================================================================" -ForegroundColor Cyan
Write-Host "Target Workspace: $resolvedRoot" -ForegroundColor Yellow
function Get-FolderSizeInfo {
param ([string]$Path)
if (-not (Test-Path $Path)) { return @{ SizeMB = 0; SizeGB = 0; Count = 0 } }
$measure = Get-ChildItem -Path $Path -Recurse -File -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum
$sum = if ($measure.Sum) { $measure.Sum } else { 0 }
return @{
SizeMB = [math]::Round($sum / 1MB, 2)
SizeGB = [math]::Round($sum / 1GB, 2)
Count = $measure.Count
}
}
# 1. Drive status before cleanup
$systemDrive = Get-PSDrive -Name C
$freeGBBefore = [math]::Round($systemDrive.Free / 1GB, 2)
Write-Host "`nCurrent Free Space on C: $freeGBBefore GB`n" -ForegroundColor Yellow
# 2. Scanning targets
Write-Host "[1/4] Scanning project 'bin' and 'obj' directories..." -ForegroundColor Green
$binObjDirs = Get-ChildItem -Path $resolvedRoot -Recurse -Directory -Force -ErrorAction SilentlyContinue |
Where-Object { $_.Name -in @('bin', 'obj') }
$binObjTotalBytes = 0
$binObjCount = 0
foreach ($dir in $binObjDirs) {
$m = (Get-ChildItem -Path $dir.FullName -Recurse -File -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
if ($m) { $binObjTotalBytes += $m }
$binObjCount++
}
$binObjGB = [math]::Round($binObjTotalBytes / 1GB, 2)
Write-Host "[2/4] Scanning Microsoft Store / MSIX 'AppPackages' directories..." -ForegroundColor Green
$appPackageDirs = Get-ChildItem -Path $resolvedRoot -Recurse -Directory -Filter "AppPackages" -Force -ErrorAction SilentlyContinue
$storeTotalBytes = 0
$storeCount = 0
foreach ($dir in $appPackageDirs) {
$m = (Get-ChildItem -Path $dir.FullName -Recurse -File -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
if ($m) { $storeTotalBytes += $m }
$storeCount++
}
$storeGB = [math]::Round($storeTotalBytes / 1GB, 2)
Write-Host "[3/4] Calculating Windows Temp folder size..." -ForegroundColor Green
$tempPath = [System.IO.Path]::GetTempPath()
$tempInfo = if (-not $SkipTemp) { Get-FolderSizeInfo -Path $tempPath } else { @{ SizeGB = 0; Count = 0 } }
Write-Host "[4/4] Calculating local NuGet cache size..." -ForegroundColor Green
$nugetCachePath = "$env:USERPROFILE\.nuget\packages"
$nugetInfo = if (-not $SkipNuget) { Get-FolderSizeInfo -Path $nugetCachePath } else { @{ SizeGB = 0; Count = 0 } }
$totalReclaimableGB = [math]::Round($binObjGB + $storeGB + $tempInfo.SizeGB + $nugetInfo.SizeGB, 2)
# Display scan table
Write-Host "`n========================= IDENTIFIED RECLAIMABLE STORAGE =========================" -ForegroundColor Magenta
$scanSummary = @(
[PSCustomObject]@{ Target = "Project Build Artifacts (bin/obj)"; Folders = $binObjCount; PotentialSavings = "$binObjGB GB" },
[PSCustomObject]@{ Target = "Microsoft Store Bundles (AppPackages)"; Folders = $storeCount; PotentialSavings = "$storeGB GB" },
[PSCustomObject]@{ Target = "Windows Temporary Files (Temp)"; Folders = $tempInfo.Count; PotentialSavings = "$($tempInfo.SizeGB) GB" },
[PSCustomObject]@{ Target = "Local NuGet Package Cache"; Folders = $nugetInfo.Count; PotentialSavings = "$($nugetInfo.SizeGB) GB" }
)
$scanSummary | Format-Table -AutoSize
Write-Host ">>> TOTAL ESTIMATED RECLAIMABLE SPACE: $totalReclaimableGB GB <<<`n" -ForegroundColor Cyan
# Safety Notice
Write-Host "================================ SAFETY GUARANTEE ================================" -ForegroundColor Green
Write-Host "* This tool NEVER deletes source code (.cs, .xaml, .cpp, .json, etc.)." -ForegroundColor White
Write-Host "* Project definitions (.sln, .csproj) and Git repositories (.git) are UNTOUCHED." -ForegroundColor White
Write-Host "* All visual textures, audio files, and raw asset files are strictly preserved." -ForegroundColor White
Write-Host "* Deleted items are purely intermediate artifacts that your IDE regenerates on Rebuild." -ForegroundColor White
Write-Host "==================================================================================`n" -ForegroundColor Green
if ($ScanOnly) {
Write-Host "Scan-only mode (-ScanOnly) completed. No files were removed." -ForegroundColor Yellow
return
}
# Prompt confirmation
if (-not $Force) {
$prompt = Read-Host "Do you want to proceed with purging these files? (Y/N)"
if ($prompt -notin @('Y', 'y', 'Yes', 'yes')) {
Write-Host "Cleanup cancelled by user." -ForegroundColor Yellow
return
}
}
Write-Host "`n>>> Starting cleanup... Please wait...`n" -ForegroundColor Cyan
# 1. Delete bin and obj
Write-Host "[1/4] Purging 'bin' and 'obj' directories..." -ForegroundColor Yellow
$deletedBinObj = 0
foreach ($dir in $binObjDirs) {
try {
if (Test-Path $dir.FullName) {
Remove-Item -Path $dir.FullName -Recurse -Force -ErrorAction SilentlyContinue
$deletedBinObj++
}
} catch {}
}
Write-Host " Cleaned $deletedBinObj build folders." -ForegroundColor Gray
# 2. Delete AppPackages
Write-Host "[2/4] Purging obsolete 'AppPackages' folders..." -ForegroundColor Yellow
$deletedAppPackages = 0
foreach ($dir in $appPackageDirs) {
try {
if (Test-Path $dir.FullName) {
Remove-Item -Path $dir.FullName -Recurse -Force -ErrorAction SilentlyContinue
$deletedAppPackages++
}
} catch {}
}
Write-Host " Cleaned $deletedAppPackages store package folders." -ForegroundColor Gray
# 3. Clean Temp
if (-not $SkipTemp) {
Write-Host "[3/4] Purging Windows Temp files..." -ForegroundColor Yellow
Get-ChildItem -Path $tempPath -Force -ErrorAction SilentlyContinue | ForEach-Object {
try { Remove-Item -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue } catch {}
}
Write-Host " Temp folder cleaned (locked in-use files safely skipped)." -ForegroundColor Gray
}
# 4. Clean NuGet
if (-not $SkipNuget) {
Write-Host "[4/4] Purging NuGet global package cache..." -ForegroundColor Yellow
try {
$null = dotnet nuget locals all --clear 2>&1
Write-Host " NuGet cache cleared successfully." -ForegroundColor Gray
} catch {
Write-Host " Warning clearing NuGet cache: $_" -ForegroundColor DarkYellow
}
}
# 3. Verification
$systemDriveAfter = Get-PSDrive -Name C
$freeGBAfter = [math]::Round($systemDriveAfter.Free / 1GB, 2)
$freedTotal = [math]::Round($freeGBAfter - $freeGBBefore, 2)
Write-Host "`n================================================================================" -ForegroundColor Green
Write-Host " CLEANUP COMPLETED! " -ForegroundColor Green
Write-Host "================================================================================" -ForegroundColor Green
Write-Host "Free Space Before : $freeGBBefore GB" -ForegroundColor White
Write-Host "Free Space After : $freeGBAfter GB" -ForegroundColor Green
Write-Host "Total Reclaimed : +$freedTotal GB" -ForegroundColor Cyan
Write-Host "================================================================================`n" -ForegroundColor Green
The One-Click Batch Launcher (clean-disk-space.bat)
Place this .bat file in your main projects root folder:
@echo off
setlocal
title Developer Workspace Disk Cleanup
cd /d "%~dp0"
echo =======================================================================
echo Developer Workspace Disk Space Cleanup Launcher
echo =======================================================================
echo.
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0_tools\Clean-DevDiskSpace.ps1" %*
echo.
echo Operation finished. Press any key to exit...
pause >nul
4. Real-World Field Results: Before vs. After
Here are the exact figures captured during a real test run across a multi-project workspace containing game engines, desktop apps, and mobile projects:
========================= IDENTIFIED RECLAIMABLE STORAGE =========================
Target Folders Potential Savings
------ ------- -----------------
Project Build Artifacts (bin/obj) 300 52.79 GB
Microsoft Store Bundles (AppPackages) 2 2.92 GB
Windows Temporary Files (Temp) 11248 3.56 GB
Local NuGet Package Cache 36055 9.33 GB
>>> TOTAL ESTIMATED RECLAIMABLE SPACE: 68.60 GB <<<
================================================================================
CLEANUP COMPLETED!
================================================================================
Free Space Before : 1.35 GB
Free Space After : 53.80 GB
Total Reclaimed : +52.45 GB
================================================================================
In under 3 minutes, 52.45 GB of clean, usable SSD storage was restored. The system immediately breathed again, without needing to uninstall a single program or risk a single line of Git history.
5. Developer Best Practices for SSD Hygiene
- Purge After Every Major Store Submission:
Once your.msixuploadbundle is accepted by Microsoft Partner Center or Google Play Console, delete the localAppPackagesfolder. You can always regenerate older builds from Git tags if needed. - Schedule a Monthly 3-Minute Routine:
Double-clickclean-disk-space.batonce a month. It prevents the slow accumulation of obsolete multi-gigabyte build artifacts. - Use
.gitignoreRigorously:
Always ensure your root.gitignoreexcludes[Bb]in/,[Oo]bj/,AppPackages/, and*.msixuploadto avoid accidentally pushing gigabytes of binary junk to remote Git repositories.
Save your storage, keep your workstation fast, and happy coding!
About Arar Games & Our Projects
Discover our indie games and connect with our studio:
- 🌐 Official Website: https://www.mayhemcorporation.com
🎮 Our Games
- Blocked: Pixel Panzer: Retro arcade tank combat with dynamic weather & boss battles.
Google Play (Android & PC) - PaintTrek: Vibrant color puzzles and pixel painting action.
Google Play | Microsoft Store (PC & Xbox) - Space Dodger: Fast-paced reflex arcade space evasion.
Google Play
📱 Follow Our Studio
- 🎵 TikTok: https://www.tiktok.com/@arargamesstudio
- 📸 Instagram: https://www.instagram.com/arargamesstudio
- 🐦 X (Twitter): https://x.com/arargamesstudio
- 📺 YouTube: https://www.youtube.com/@koreaaria
- 🧵 Threads: https://www.threads.net/@arargamesstudio
- 📘 Facebook: https://www.facebook.com/arargamesstudio
Hiç yorum yok:
Yorum Gönder