The Storage War: Bypassing Go Drive Colon Bugs to Reclaim 350GB of GGUF Bloat
Act IV of the ThreatLabs CTI stack has officially hit its structural crunch milestone, and today we’re talking about the absolute high-latency mess that happens when you let model registries sprawl without a clear storage design. After building out the Intel Arc Pro B70 compute engine last month, we went completely local and token-free. We were downloading models like a digital hoarder: a 7B container model here, a 27B dense variant there, a few custom coding fine-tunes, and an abliterated variant of an uncensored quantization.
By June 2026, the local framework library had swollen to an unmitigated 480GB of raw model weight files spread erratically across multiple partitions. The Windows C: system drive was literally gasping for disk space.
Worse, the models were fractured across three distinct runspaces—Ollama (native Windows), Ollama (WSL2 Debian runtime), and LM Studio. Each runtime environment was maintaining its own independent system cache folder, frequently duplicating the exact same base GGUF weights under separate hash transformations. We were drowning in storage debt, and the system disk parameters were hitting their absolute boundaries.
Time for some aggressive directory junctions and automated cache pruning surgery.
Pitfall 12: The Go Parser Drive-Colon Split Trap
The first design goal was straightforward: move the entire model storage block off the choked C: system partition and consolidate it onto a dedicated high-capacity H: NVMe array pool.
The naive way to execute this on Windows is to change your environment handles or drop a basic relative symbolic link pointer using mklink /D. Except if you try that with Ollama’s native engine, the underlying Go compiler parser hits a hard pathing trap. Go’s model directory configuration handles suffer from a legacy path-splitting bug; when it scans an environment variable or directory path containing an explicit volume colon drive identifier (like H:\), it borks the path resolution completely, treats the delimiter as an invalid network segment, maps an orphaned target folder structure, and crashes out on launch.
Worse, if you're trying to route native standalone workflows through llama-server.exe in directory router mode, the engine slams into a hard two-subfolder search limitation. If your GGUF models are nested deeper than two target subdirectories below the parent folder parameter, the scanner ignores them entirely, rendering your local inference fabric blind.
The fix required yanking the environment path assignments entirely, bypassing the drive-colon character split loop, and using strict, low-level NTFS directory junctions (/J) on the host system command line to fake out the binary engines.
:: Quit Ollama and kill off all active inference process handles first
:: Forcefully map a system-level NTFS Directory Junction bypass
mklink /J "C:\Users\jamz\.ollama\models" "Z:\Development\ollama\models"
:: Bridge LM Studio to the same unified hub cache directory mapping
mklink /J "C:\Users\jamz\.cache\lm-studio\models" "H:\Development\lmstudio\models"Windows now treats the active model repositories as native, un-aliased local paths directly inside the home directory string, resolving the Go split trap instantly.
Next, we map the POSIX path inside the WSL2 Debian runspace to point to the exact same storage pool, eliminating cross-OS duplicate caches forever:
# Forcefully symlink the WSL runtime model folder back to the Windows NTFS partition mount
ln -s /mnt/z/Development/ollama/models ~/.ollama/modelsPitfall 13: The Orphaned Blob Sprawl Trap
With the junctions laid, the runtimes were finally sharing the same physical drive matrix. But yanking models via ollama rm leaves a nasty residue. Ollama breaks models into cryptographic sha256 blob names inside the database tier. If you overwrite or manipulate model manifests manually across the cross-OS boundary, the link maps shatter, leaving hundreds of gigabytes of untracked, detached binary blobs eating space inside the storage pool without showing up in your active manifests.
Never trust built-in application pruners to handle raw system garbage collection. Wrote a strict automated janitor loop script—clean-blobs.py—that runs directly inside the model cache directory, parses every live active manifest JSON index file, maps the valid hashes, and forcefully wipes out any detached, orphaned binary weights from the drive pool.
The Workaround: clean-blobs.py
import os
import json
import glob
# Consolidate target directory handles to the unified junction pool
blobs_dir = "Z:/Development/ollama/models/blobs"
manifests_dir = "Z:/Development/ollama/models/manifests/registry.ollama.ai/library"
print("Parsing active manifest indexes for valid registry keys...")
valid_blobs = set()
# Parse every live model manifest file to extract registered sha256 links
for manifest_path in glob.glob(os.path.join(manifests_dir, "**/*"), recursive=True):
if os.path.isfile(manifest_path):
try:
with open(manifest_path, 'r') as f:
data = json.load(f)
for layer in data.get('layers', []):
valid_blobs.add(layer.get('digest').replace('sha256:', 'sha256-'))
if 'config' in data:
valid_blobs.add(data['config'].get('digest').replace('sha256:', 'sha256-'))
except Exception as e:
print(f"Skipping borked index entry {manifest_path}: {e}")
print(f"Tracking {len(valid_blobs)} authenticated weight files across registries.")
# Sweep the physical blobs directory and forcefully prune orphaned weights
pruned_bytes = 0
for blob_file in os.listdir(blobs_dir):
if blob_file not in valid_blobs:
blob_path = os.path.join(blobs_dir, blob_file)
try:
pruned_bytes += os.path.getsize(blob_path)
os.remove(blob_path)
print(f"Forcefully purged orphaned blob file: {blob_file}")
except Exception as e:
print(f"Failed to clear disk handle for {blob_file}: {e}")
print(f"Garbage collection verified. Reclaimed {pruned_bytes / (1024**3):.2f} GB of bloated storage debt.")Executed the janitor script across the unified drive partition. The cleanup routine forcefully culled over 350GB of untracked weight files from the drive pool on the first pass, stabilizing the disk bounds and leaving only our elite local model registries active.
The Core Fleet Standings
With our storage boundaries locked down, we consolidated our activeRegistry matrix to a lean, dual-model subagent loop using only the top-performing quantized engines:
1. gemma-4-26B-A4B-it-qat-UD-Q4_K_XL.gguf (Primary Control Ingress)
2. Qwen3-Coder-30B-A3B-Instruct-UD-Q4_K_XL.gguf (CTI Ingestion & JSON Schema King)
3. DeepHat-V1-7B.Q4_K_M.gguf (Ultra-fast DevSecOps Triage Container)- gemma-4-26B-A4B-it-qat-UD-Q4_K_XL.gguf (Primary Control Ingress)
- Qwen3-Coder-30B-A3B-Instruct-UD-Q4_K_XL.gguf (CTI Ingestion & JSON Schema King)
- DeepHat-V1-7B.Q4_K_M.gguf (Ultra-fast DevSecOps Triage Container)
The storage war is officially over, the junctions are rock-solid, and the local drive caches are running completely unified without a single byte of duplicated overhead. Act IV is approaching the finish line. Next week in Post 11, we are launching "The Gauntlet"—putting these local models through a brutal, bespoke 7-task validation harness to test their actual logical compliance when processing malicious threat data loops.
See ya later. Happy tinkering!