Creating an SMR Archive with HuskHoard
A practical walkthrough for building a cold-storage vault out of cheap SMR drives — and why it beats a RAID array for this job.
If you've ever been told "never buy SMR drives," you were given good advice for the wrong reason. SMR (Shingled Magnetic Recording) drives are terrible under a normal filesystem and a RAID controller. They are excellent as an archive medium, if — and only if — the software writing to them understands how they physically work. That's the specific niche HuskHoard is built for: an open-source (AGPL v3), Rust-based data-tiering engine for Linux that treats hard drives like tape and becomes a host manager for SMR drives.
This walkthrough covers setting up a HuskHoard archive backed by SMR storage volumes, and then digs into why this architecture beats a traditional RAID array for cold data — on cost, power, heat, mechanical wear, and failure behavior.
First, what HuskHoard actually does
HuskHoard sits between your fast NVMe "hot tier" and your slow, cheap "cold" storage (SMR/CMR drives, LTO tape, or cloud buckets). Instead of using FUSE, it uses the Linux fanotify kernel API to watch a directory in user-space. A background "Janitor" process finds cold files, compresses them into 16MB Zstd frames, and streams them out to your archive drives. It leaves behind a sparse "husk" — a stub file that still shows its full logical size to your OS. When something tries to open that stub, HuskHoard pauses the process, recalls the data, and resumes it — transparently, with no FUSE mount overhead. All of the actual filesystem metadata (paths, versions, byte offsets) lives in a SQLite catalog kept on the NVMe hot tier, not on the archive drives themselves. That last detail is the key to everything below.
Why SMR specifically
CMR (Conventional Magnetic Recording) drives write data in discrete circular tracks with small gaps between them — a write head can update one track without touching its neighbors. SMR drives overlap those tracks like roof shingles to pack far more data onto the same platter. That's great for density and terrible for random writes: updating one overlapped track means reading, erasing, and rewriting a whole "zone" (typically ~256MB) to avoid corrupting the neighboring track. This is why SMR drives fall over inside ZFS or ext4 — those filesystems constantly scatter tiny random metadata writes (journals, inode tables, free-space bitmaps) across the disk, and every one of those small writes can trigger a 256MB read-modify-write cycle. The drive's small CMR write cache fills up, throughput collapses to a couple of MB/s, and the actuator thrashes itself into an early grave.
SMR drives have exactly one superpower: sequential, append-only writes. Start at the beginning of an empty zone and never write backward, and the shingled tracks stack perfectly — no read-modify-write penalty at all. That's precisely how HuskHoard writes: it never mounts the SMR drive with a filesystem, never journals to it, and never sends it a single metadata update. It hands the raw block device to its MultiTapeWriter, which buffers incoming data in RAM, compresses it, and flushes strictly 4KB-aligned, sequential writes via O_DIRECT. To the SMR drive, HuskHoard just looks like a very fast tape drive.
Setting up the archive
The steps below follow the project's own quick-start, adapted for a real SMR drive rather than the .img test file used in the tutorial. This assumes Ubuntu 22.04/24.04 (or another distro with kernel 5.1+ and fanotify).
1. Install prerequisites
sudo apt update
sudo apt install -y build-essential rclone libcap2-bin attr pkg-config libsqlite3-dev git
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
2. Clone and build
git clone https://github.com/huskhoard/huskhoard.git
cd huskhoard
cargo build --release
3. Grant kernel capabilities (no root daemon)
HuskHoard is explicitly designed to run as your normal user, not root. It only needs two capabilities to intercept file access via fanotify and read arbitrary files during recall:
sudo setcap cap_sys_admin,cap_dac_read_search+ep target/release/huskhoard
4. Identify your SMR drive — and don't format it
This is the part people get wrong. Find the raw block device with lsblk, e.g. /dev/sdb. Do not put a filesystem on it. Do not mount it. HuskHoard writes directly to the raw device so it stays in full control of write ordering — that's what preserves the sequential-append pattern SMR needs.
./target/release/huskhoard format --tape-dev /dev/sdb
Running format for the first time generates a husk_config.toml in your working directory.
5. Configure the volume
Open husk_config.toml and point it at your hot tier and archive drive(s). A minimal single-drive setup looks like:
primary_volumes = ["/dev/sdb"]
hot_tier = "/home/YOUR_USERNAME/huskhoard/hot_tier"
max_age_days = 30
janitor_interval_secs = 3600
http_port = 8080
# Safety settings
hot_tier_max_usage_percent = 80
min_free_space_gb = 50
For redundancy, add a second SMR (or cloud) volume as a replication_volumes target with replicas = 1 — HuskHoard will write to both simultaneously via the same multiplexed I/O path.
6. Launch the daemon and test
./target/release/huskhoard daemon
In a second terminal, drop a large file into your hot tier directory and wait for the Janitor interval to pass:
dd if=/dev/urandom of=hot_tier/dummy_data.bin bs=1M count=500
du -h hot_tier will show it shrink to a sparse stub once archived, while ls -l still reports its full logical size. Opening the file triggers an instant, transparent recall from the SMR volume.
Useful commands going forward:
# Stream a file directly off the archive with zero local extraction
./target/release/huskhoard cat --file-path /media/movies/scifi.mp4 | mpv -
# Check capacity and usage
./target/release/huskhoard info --tape-dev /dev/sdb
# Verify data integrity (BLAKE3 bit-rot scrub)
./target/release/huskhoard scrub --tape-dev /dev/sdb
# Garbage-collect / consolidate a volume
./target/release/huskhoard repack --source-tape /dev/sdb --dest-tape /dev/sdc
For anything beyond a handful of drives, HuskHoard uses a "Sticky Drive" fill strategy: it writes to one drive until it hits your configured free-space floor, then permanently moves to the next, leaving the rest spun down. A 40-drive production config typically splits drives into a primary pool and a mirrored replication pool, or adds a cloud bucket as overflow once local drives fill up — all just entries in primary_volumes / replication_volumes / failover_volumes.
Why this beats RAID for cold data
Cost per terabyte. Because HuskHoard acts a host manager it never need a filesystem's write-amplification headroom or RAID parity overhead, you can buy the cheapest medium that fits the access pattern. Rough figures from current pricing: archive-class SMR HDDs run around $14–16/TB, general NAS CMR drives around $20–25/TB, and NVMe (used only for the small hot tier and catalog) around $75–100/TB. At the very cold end, LTO-9 tape comes in near $5/TB — about six times cheaper than CMR and roughly fifteen times cheaper than NAS SSD for the same 100TB of storage.
Power draw. A striped RAID array has to spin up every disk to service a single read, and routine metadata chatter (Samba pings, Plex library scans, ls) keeps the whole array from ever sleeping. An 8-drive RAID-Z2 pool idling at roughly 60W continuous can cost on the order of 500 kWh a year just to keep metal spinning for data you touch rarely. Because HuskHoard keeps all metadata on the NVMe hot tier, the archive drives see zero filesystem chatter and can drop into true deep sleep — 0W — until the one specific drive holding a requested file is woken up.
Heat and mechanical wear. Random I/O is what kills spinning drives — the actuator thrashes back and forth across the platter, and the drive runs hotter under constant repositioning. HuskHoard's append-only, sequential write pattern eliminates that thrashing almost entirely, which is doubly important for SMR drives (where random writes also trigger the write-amplification death spiral described above). Practically, this means archive drives run cooler and see meaningfully less mechanical stress than the same drives would inside an always-spinning array.
Vibration and acoustic load. This follows from the same mechanics: fewer drives spinning simultaneously means less cumulative rotational vibration transmitted through a shared chassis or rack, and a head that only ever streams in one direction generates far less seek noise and vibration than one being yanked across the platter by scattered random writes. If you've built a home server and cared about acoustic or vibration isolation, a "one drive spins at a time" design is a meaningfully quieter physical system than eight drives striped together.
Failure domain. RAID treats the array as one unit — lose too many member disks and you lose the whole pool, and rebuilding after a single failure means hammering every remaining drive at 100% I/O for hours or days, during which a second failure can be catastrophic. HuskHoard volumes are independent: each drive holds whole files, not stripes. If a drive dies, you lose only the files that were on it (and only if you didn't configure a replica). Recovery is just copying the missing files from the replication volume — no parity math, no array-wide rebuild stress.
Hardware portability. Each HuskHoard volume writes a UUID to the start of the device, so a drive can be unplugged and moved to a different port, enclosure, or even machine, and the catalog will still recognize it. That's a meaningfully different operational story than a RAID member disk, which is generally tied to its array.
Where RAID (or ZFS) still wins
To keep this balanced: this architecture is a trade specifically for cold, infrequently accessed data. It is not a replacement for RAID in every context.
- Random-access, hot workloads (databases, live VM storage, active project files) still want an SSD or a real RAID/ZFS pool — HuskHoard's own docs are explicit that SMR/append-only volumes are wrong for that job.
- Redundancy is N-way mirroring, not erasure coding. HuskHoard's replication is "keep N full copies," not RAID6/RAIDZ2-style parity. For a given amount of raw capacity, mirroring is less storage-efficient than parity schemes.
- The catalog is a single point of dependency. All the metadata that makes stubs meaningful lives in one SQLite database on your hot tier. Back it up (the project supports exporting it to Parquet) — losing it doesn't destroy your payload data on the archive drives, but it does make it much harder to find.
The short version
RAID solves a problem HuskHoard doesn't have: keeping hot data available with disks striped for throughput. For a cold archive, that architecture actively works against you — it forces every disk to spin for every read, buries metadata inside the same random-write chaos that kills SMR drives, and turns a single failed disk into a multi-day, high-stress rebuild. Pairing cheap SMR drives with a tool built around sequential, tape-like writes turns that liability into the cheapest, coolest, and quietest way to store data you rarely touch but never want to lose.
Top comments (0)