The Storage Paradox
There it was, staring at me from the OPNsense dashboard. A 1TB drive with 4.4GB used. Less than 1% utilization. My firewall was using less storage than a modern smartphone photo album.
This felt like architectural malpractice.
The Junk Drawer Discovery
You know that drawer. The one filled with cables from 2015, dead hard drives, and USB sticks of unknown provenance. I was hunting for a spare cable when I found it - a dusty 32GB USB drive with a faded “TS32GMSA370” label.
$ sudo smartctl -a /dev/sdc
Model Family: Silicon Motion based SSDs
Device Model: TS32GMSA370
User Capacity: 32,017,047,552 bytes [32.0 GB]
Power_On_Hours: 6931
Remaining_Lifetime_Perc: 95%
Not bad for archaeological tech. 6931 hours of runtime (about 9 months of continuous use) and still showing 95% remaining lifetime. This little survivor had been through some battles.
The Math That Made Sense
Here’s the beautiful irony:
- Current setup: 1TB drive, 4.4GB used (995GB wasted)
- USB option: 32GB drive, 4.4GB used (27GB free)
That’s still a 6:1 overhead ratio. More than enough for logs, configs, and future growth. Plus, I could repurpose that 1TB for something that actually needs storage.
Stress Testing the Relic
Before trusting my network’s fate to this USB veteran, I put it through the gauntlet:
# The gentle approach (after dd crashed the system)
$ tmux new-session -d -s stress_test 'sudo badblocks -v -w -s /dev/sdc'
# The proper tool
$ sudo fio --name=seqwrite --ioengine=libaio --iodepth=1 \
--rw=write --bs=1m --direct=1 --size=1g --numjobs=1 \
--runtime=60 --group_reporting --filename=/dev/sdc
The drive handled sequential writes like a champ. No bad blocks, consistent performance, and temperatures stayed reasonable. This wasn’t just surviving - it was thriving.
The Migration Philosophy
Here’s where the FreeBSD disk layout works in our favor. The installer will see both drives:
- ada0: Current 1TB system disk (existing OPNsense)
- ada1: New 32GB USB target
The installer can detect and import the configuration from ada0 automatically. Choose UFS for the new filesystem - simple, reliable, and perfect for USB storage patterns. No network pointing needed when both disks are physically present.
The USB Optimization Reality
USB-based firewalls aren’t new, but they require thinking differently about storage:
Write Optimization:
- Logs rotation becomes critical
- Config changes are infrequent (perfect for flash)
- Most data is ephemeral (connection states, temp files)
Performance Reality:
- Network processing: CPU-bound ✓
- Rule evaluation: Memory-bound ✓
- Config reads: Infrequent ✓
- Heavy writes: Only during updates
OPNsense on USB isn’t a compromise - it’s a right-sized solution.
The Partition Archaeology
The USB came pre-loaded with Home Assistant OS:
$ sudo fdisk -l /dev/sdc
Device Start End Sectors Size Type
/dev/sdc1 2048 67583 65536 32M EFI System
/dev/sdc2 67584 116735 49152 24M Linux filesystem
/dev/sdc3 116736 641023 524288 256M Linux filesystem
/dev/sdc4 641024 690175 49152 24M Linux filesystem
/dev/sdc5 690176 1214463 524288 256M Linux filesystem
/dev/sdc6 1214464 1230847 16384 8M Linux filesystem
/dev/sdc7 1230848 1427455 196608 96M Linux filesystem
/dev/sdc8 1427456 62533262 61105807 29.1G Linux filesystem
Classic HassOS layout with A/B update partitions. The OPNsense installer would wipe this clean and create its own optimized layout. From one automation system to another - there’s poetry in that transition.
The Liberation Strategy
Moving OPNsense to USB unlocks the main system for “more serious stuff”:
- Docker services that actually need storage
- Build caches that benefit from SSD speed
- Development environments with heavy I/O
- Media storage for services that consume space
The firewall gets right-sized storage, and everything else gets to breathe.
Installation Day
The beauty of this approach is its simplicity:
- Insert USB into NUC (alongside existing 1TB)
- Boot installer
- Select ada1 (32GB USB) as target
- Choose UFS filesystem
- Import configuration from ada0
- Wait for magic to happen
- Remove old disk, done
Minimal downtime - just the reinstallation time. No network credentials. No complex migration scripts. No reconfiguration needed. Just FreeBSD disk detection and local config import doing the heavy lifting.
The Lesson in Right-Sizing
This wasn’t really about saving 995GB of disk space. It was about intentional architecture - matching resources to actual requirements instead of defaulting to “bigger must be better.”
Sometimes the best solution is literally gathering dust in your junk drawer, waiting for the right problem to solve.
# The new reality
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/da0p3 27G 4.4G 21G 18% /
Perfect. Right-sized, battle-tested, and ready for years of reliable service. The 1TB drive lives on, freed to handle workloads that actually deserve that capacity.
Aftermath
The migration completed flawlessly. All firewall rules, VPN configs, and network settings transferred seamlessly. The NUC now runs cooler, uses less power, and the network performance is identical.
Most importantly, I learned to trust the math over the marketing. Sometimes 32GB of the right storage beats 1TB of the wrong storage.
The USB stick that survived years of random data transfers found its purpose as the foundation of my home network. Not bad for a junk drawer rescue.