The Data Hoarder's Dilemma

If you run a Plex, Emby, or Jellyfin server at home, you know exactly how this story goes. You start with a modest 4-bay Synology NAS. A few years later, you're building a massive Unraid or TrueNAS server filled with 100 Terabytes of spinning rust.

A single uncompressed 4K Blu-ray remux can easily consume 60 to 80 Gigabytes. Storing thousands of these movies, alongside complete television series, quickly becomes a financial burden. Not just in drive costs, but in electricity, cooling, and the terrifying prospect of needing to back it all up.

You have a vast library, but realistically, you only watch 5% of it actively. The rest sits idle, drawing power, waiting for that one day three years from now when someone requests it.

Moving that data to offline LTO Tape or cheap cold cloud storage makes perfect sense. But traditionally, if you move a movie to a cold tier, Jellyfin loses it. The movie vanishes from your library UI, breaking your meticulously curated collections.

Taming the Metadata Scanners

HuskHoard solves the "missing media" problem by stubbing files. When the Husk Janitor archives an 80GB movie to a tape drive or cloud remote, it punches a hole in the local file. The file remains visible to the OS at its full 80GB size, but consumes 0 bytes of disk space.

But there is a catch when dealing with Media Servers. Jellyfin and Plex use background processes (like ffprobe) to scan your library constantly, generating thumbnails, extracting subtitles, and detecting intros.

If you use HuskHoard's standard fanotify kernel intercept, every time Jellyfin scans a stubbed movie, HuskHoard would think a user is trying to watch it and trigger an massive restore from tape. You'd be locked in a nightmare of endless tape-swapping.

To prevent this, HuskHoard's daemon specifically ignores background indexers. In daemon.rs, we maintain a customizable ignore list:

// Inside daemon.rs — Background Scanner Ignore List let ignore_list = ["rg", "tracker-miner-f", "ffprobe", "jellyfin", "Plex Media Scanner"]; if ignore_list.contains(&proc_name.as_str()) { info!("[Daemon] Ignoring background read from '{}' to keep file stubbed.", proc_name); }

When Jellyfin scans a stubbed file, HuskHoard simply feeds it safe, zeroed-out bytes (or serves the cached metadata) and allows the scan to complete instantly without ever touching the tape drive. Your Jellyfin UI remains gorgeous, fully populated, and completely intact, even if 95% of the underlying video files are sitting in a box on your shelf.

The HTTP Streaming Gateway

If Jellyfin is blocked from triggering automatic kernel restores, how do you actually watch the movie?

This is where the magic happens. HuskHoard ships with a built-in, lightweight HTTP Streaming Gateway (located in gateway.rs). Instead of pointing Jellyfin at the local stubbed file, you can add HuskHoard's local HTTP server as a custom stream source, or utilize .strm files.

1. User Hits Play
Jellyfin reads the .strm file pointing to http://localhost:8080/stream/Movies/Dune.mkv
2. HTTP Request
HuskHoard receives the GET request and queries the SQLite Catalog.
3. Direct Stream
Husk reads the tape/cloud and pipes bytes directly to the HTTP socket.

The beauty of the HTTP Gateway is that the file is never restored to the local SSD. HuskHoard reads the data from the LTO tape or Cloud bucket and streams it directly into memory, passing it straight to Jellyfin. This is true Zero-Disk delivery.

Seeking, Scrubbing, and Range Headers

If you've ever tried to stream video from a cold storage tier, you know that skipping ahead 45 minutes usually breaks the stream. Standard HTTP servers try to download the entire file from the beginning.

HuskHoard's HTTP Gateway is fully compliant with RFC 7233 (HTTP Range Requests). When you scrub forward in the Jellyfin web player, the browser sends an HTTP Range header requesting specific bytes (e.g., Range: bytes=42000000-).

// From gateway.rs — Parsing the Range Header for Media Players if header_line.to_lowercase().starts_with("range: bytes=") { let range_val = header_line[13..].trim(); let split: Vec<&str> = range_val.split('-').collect(); range_start = split[0].parse().unwrap_or(0); } // Send the 206 Partial Content Response let headers = format!( "HTTP/1.1 206 Partial Content\r\nContent-Type: video/x-matroska\r\nContent-Range: bytes {}-{}/{}\r\n\r\n", range_start, end, total_size );

HuskHoard catches this Range request, utilizes the StreamGate jump tables in the SQLite database, and instantly fast-forwards the tape drive (or issues a targeted cloud API call) to that exact byte offset. You get instant O(1) seek times on 80GB media files without downloading the parts you skipped.

Jellyfin + HuskHoard Architecture

Setting this up requires a slight shift in how you organize your media library, but the long-term savings are massive.

1. The Ingest Folder

You run Radarr, Sonarr, or MakeMKV normally, dropping files into your local /hot_tier. HuskHoard archives them to tape in the background and punches the holes to save your disk space.

2. .STRM Generation

Instead of pointing Jellyfin at the /hot_tier directory directly, you run a lightweight script that generates a folder full of .strm files (text files containing the http://localhost:8080/stream/... URL) for Jellyfin to scan.

3. The Prompt

If a user hits play on a movie that is currently on an ejected tape, HuskHoard pauses the stream and sends a notification (via Discord/Telegram/UI) telling you to insert `Tape Vol-03`. If it's a cloud remote, it just streams instantly.

By leveraging HuskHoard's HTTP Gateway, you can build a 100 Terabyte media server using nothing but a cheap Intel NUC, a single 1TB SSD for caching/metadata, and a stack of $40 used LTO tapes (or a cheap Backblaze B2 bucket).

You keep the beautiful, instantaneous Jellyfin UI, but eliminate the heat, noise, and massive cost of running a 15-drive hard drive array in your living room.