Your Media Library Is Too Big (And It Doesn’t Have To Be)
You’ve got 500 GB of 1080p h264 files. Your storage is crying. Your ISP cap is sweating. Meanwhile, your server can push h265 or AV1 to your players without breaking a sweat, and save you 40–60% of that disk space in the process.
But manually re-encoding 500 files? That’s like hiring a forklift to move a couch. Technically it works, but you’ve got better things to do at 2 AM.
Enter Tdarr. It’s a self-hosted transcoding orchestrator that runs on your homelab, watches your media folders, and silently chews through your backlog with the codec strategy you decide. GPU acceleration, CPU fallback, granular control — no cloud vendor tax, no “we’re transcoding your files” splash screens. Just dumb, fast encoding.
Here’s how to set it up and not hate yourself three months in.
What Tdarr Does (And Why You Want It)
Tdarr isn’t a media player. It’s not a file manager. It’s a transcoding daemon that runs in the background, watching your library and automatically re-encoding files based on rules you define.
The premise:
- Point Tdarr at your media folder (
/mnt/media/) - Write or pick a “flow” — a sequence of checks and codecs (“if file is h264 AND larger than 2GB, transcode to h265”)
- Tdarr spawns worker nodes (on the same machine or across your homelab)
- Files get encoded, originals are deleted, storage shrinks
- You never think about it again
Why this beats manual work:
- Batch processing — queues 200 files, runs them in parallel
- Codec choice — h264 → h265 (HEVC) for broad compatibility, or h265 → AV1 for next-level compression
- GPU acceleration — NVIDIA NVENC, AMD VCE, Intel QSV — renders a 2-hour film in 20 minutes instead of 2 hours
- Atomic updates — only replaces the original once the new file is verified
- Selective re-encoding — “only touch files over 3GB” or “skip files already in h265”
- Health checks — Tdarr has plugins for audio, subtitles, stream validation
- No vendor lock-in — it’s self-hosted, open-source, runs on Docker
The math: A 1080p h264 film (4–5 GB) becomes 1.5–2 GB in h265. AV1 pushes it to 800 MB–1.2 GB. Multiply that by 200 films. You’re looking at 600–800 GB freed up, sometimes more.
The Tdarr Architecture: Server + Nodes
Tdarr has two pieces:
Server — the brain. Web UI, job queue, database, metadata cache. Runs once.
Node(s) — the workers. Do the actual transcoding. Can run 1, 5, or 20 depending on your CPU/GPU count.
Single-machine setup:
Your server (Docker) ├─ Tdarr server container ├─ Tdarr node #1 (same machine) └─ Tdarr node #2 (same machine, if multicore)Multi-machine (homelab flex):
Your NAS running Tdarr serverYour old gaming PC running Tdarr node (with NVIDIA GPU)Your Dell SFF running Tdarr node (CPU-only, for low-priority backlog)The server talks to nodes via HTTP. Nodes download files from shared storage (NFS, SMB), encode locally, upload the result back. Dead simple.
For this guide, I’m assuming a single machine with Docker and optional GPU. If you’re spreading work across machines, the node setup is identical — just point to the same media folder (NFS mount or SMB share).
Docker Compose Setup
Here’s the bare-minimum server + single node:
version: "3.8"services: tdarr-server: image: ghcr.io/haveagitgat/tdarr:latest container_name: tdarr-server restart: unless-stopped network_mode: host # For easy local access volumes: - /mnt/data/tdarr:/home/Tdarr/Server - /mnt/data/tdarr-logs:/home/Tdarr/Logs - /mnt/media:/media:ro # Your media library (read-only for safety) environment: - TZ=UTC - "PUID=1000" - "PGID=1000"
tdarr-node: image: ghcr.io/haveagitgat/tdarr_node:latest container_name: tdarr-node restart: unless-stopped network_mode: host volumes: - /mnt/data/tdarr-node:/home/Tdarr/Node - /mnt/media:/media # Writable so node can replace files environment: - TZ=UTC - "PUID=1000" - "PGID=1000" - "TDARR_SERVER=127.0.0.1" - "TDARR_PORT=8266" - "TDARR_NODE_PORT=8267" depends_on: - tdarr-server deploy: resources: limits: cpus: "4" memory: 4GWith GPU (NVIDIA):
Add runtime: nvidia to the node service and use an NVIDIA-enabled base image:
tdarr-node: image: ghcr.io/haveagitgat/tdarr_node:latest container_name: tdarr-node restart: unless-stopped network_mode: host runtime: nvidia volumes: - /mnt/data/tdarr-node:/home/Tdarr/Node - /mnt/media:/media environment: - TZ=UTC - "PUID=1000" - "PGID=1000" - "TDARR_SERVER=127.0.0.1" - "TDARR_PORT=8266" - "TDARR_NODE_PORT=8267" - "NVIDIA_VISIBLE_DEVICES=all" depends_on: - tdarr-serverBring it up:
docker-compose up -dHit http://localhost:8265 — the Tdarr UI. Give it 30 seconds to initialize.
Flows: The Actual Transcoding Logic
A flow is Tdarr’s way of saying “here’s the recipe.” It’s a series of steps: check codecs, check file size, decide to transcode (or not), pick a codec, set quality targets.
Tdarr ships with community-built flows. You can use those, remix them, or write your own. Here’s what a typical flow looks like:
“Transcode h264 to h265 if > 2GB”:
- Check input codec — is it h264? If not, skip.
- Check file size — is it bigger than 2 GB? If not, skip.
- Set output codec — h265
- Set quality — CRF 23 (visually lossless, good compression ratio)
- Encode — ffmpeg with your chosen hardware encoder (libx265, hevc_nvenc, hevc_qsv, etc.)
- Verify output — streams match? No corruption? Audio preserved? If yes, replace original.
In the UI, you’ll find these flows in the Libraries tab. Most people start with something like:
- “H264 to H265” — converts older h264 files to modern HEVC for 40% smaller footprint
- “H265 to AV1” — takes h265 and compresses further for 25–40% smaller (but slower to encode)
- “Audio codec fix” — ensures all files have compatible audio (AAC, AC3, etc.) and removes problematic streams
You can run multiple flows sequentially. For example:
- Run “H264 to H265” first, let it finish
- Then run “H265 to AV1” on the result
- Then run “Audio codec fix”
This gives you granular control and lets you bail out at any step if something goes sideways.
CPU vs GPU: When to Use What
GPU transcoding (NVIDIA NVENC, AMD VCE, Intel QSV):
- Speed — 1080p h264→h265 in 10–20 minutes on GPU vs 90–120 on CPU
- Quality loss — Minimal with modern encoders, negligible at CRF 20–23
- Power — GPUs draw more watts, but you’re done faster (net neutral or better)
- Downsides — Cost ($200–500 for a capable card), driver headaches (NVIDIA especially)
CPU transcoding (libx265, libvpx-vp9, libaom for AV1):
- Speed — Slower, obviously. A 2-hour film takes 2–4 hours on a mid-range CPU
- Quality — Slightly better at same CRF than GPU (CPU encoders are more thorough)
- Cost — Nothing extra; you use your existing CPU
- Power — Fans spin, bills tick up, but it’s what you’ve got
- Best for — Night-time queuing, low-priority backlog, machines you already run 24/7
My take: If you have a spare GPU or a machine with NVIDIA/AMD graphics, use it. If you’re on an old NAS or a CPU-only box, queue transcodes for night hours and let the CPU chew. Tdarr queues are smart — it’ll batch work and respect your CPU/memory limits.
Running Your First Flow
-
Point Tdarr to your library:
- UI → Libraries → Create
- Path:
/media(or wherever your videos live) - Scan folder: Enable (let Tdarr crawl and index)
-
Pick a flow:
- Go to Flows
- Sort by “Popular” — grab something like “H.264 to H.265 (HEVC)”
- Review the settings (CRF value, codec choice)
-
Assign flow to library:
- Libraries → Your library → Transform → Assign flow
- Set a maximum file age (e.g., “only touch files older than 7 days”) to avoid re-encoding stuff you just added
-
Let it rip:
- UI shows a Job queue. Files tick through one by one (or in parallel if you’ve got multiple nodes)
- Watch the Health check column — green = good, yellow = warnings, red = failed
- Failed files stay in-place; you can manually review and re-queue
-
Monitor:
- Check logs in Logs tab if something breaks
- CPU/memory usage is visible in the Node Health panel
Storage Savings Math (And Why It Matters)
Let’s say you’ve got a modest 1080p Plex library: 200 films, average 4 GB each. 800 GB total.
Scenario A: Convert all to h265 (CRF 23)
- Average per film: 1.5 GB
- Total: 300 GB
- Savings: 500 GB — that’s a whole 6TB drive you don’t need
Scenario B: Convert all to AV1 (CRF 30, slower)
- Average per film: 900 MB
- Total: 180 GB
- Savings: 620 GB — basically two drives
Scenario C: Hybrid (h265 for older stuff, AV1 for new)
- Older 200 films in h265: 300 GB
- New 50 films in AV1: 45 GB
- Total: 345 GB
- Savings: 455 GB — balanced quality/speed/storage trade-off
The time investment? A few nights of CPU work (or an afternoon with a GPU). After that, it’s automatic — new files get transcoded on import if you set up a watch folder.
Common Gotchas (Because Murphy’s Law Is Real)
Subtitle/audio tracks disappear:
- Some flows are aggressive about stripping streams. Before you run a large batch, test on 5–10 files and spot-check in your player.
- Add a health check plugin to the flow that validates audio/sub preservation.
Encoding hangs (especially GPU):
- NVIDIA drivers crash sometimes. If a node stops responding, restart the container.
- Tdarr auto-detects and re-queues hung jobs; check logs for patterns.
“I need the original back”:
- Tdarr backs up the original while encoding. If the new file fails verification, it keeps the original.
- If you manually delete a transcoded file and want the original back, you’ll need a backup. Think before you queue.
Library scanning is slow:
- First scan of 5000+ files can take hours. Run it during off-peak hours or overnight.
- After that, incremental scans are quick.
Codec compatibility:
- Not all players support h265 or AV1 (looking at you, older Fire TVs and some browsers).
- If you’re streaming to multiple devices, stick with h265 or use two library pools (h265 for Plex, h264 for browsers).
The Lazy Approach (If You’re Short on Patience)
You don’t have to transcode everything. Tdarr can be selective:
- “Only touch files over 3 GB” — saves the biggest files first
- “Only h264, skip h265” — avoids re-encoding already-optimized files
- “Folder whitelist” — e.g.,
/media/filmsbut not/media/anime(anime is weird, leave it) - “Only files older than 6 months” — let new imports settle before re-encoding
Start conservative. Queue a 50-file test batch, let it sit overnight, wake up, spot-check 5 random files in your player. If they play fine and the quality is acceptable, unleash it on the full library.
When Tdarr Is Overkill (And You Don’t Need It)
- You’ve got unlimited storage and bandwidth
- You only watch stuff once (no point optimizing)
- Your player doesn’t support h265 or AV1 (yet)
- You’re using a commercial streaming service anyway (Plex Pass, Jellyfin, Emby) — they handle transcoding on the fly
For everyone else: Tdarr is the difference between “my homelab storage costs $50/month in extra drives” and “my drives are half full and I’m sleeping better.”
Set it and forget it. Your 2 AM self will appreciate the freed-up disk space.
Next Steps
- Clone the Compose file above, tweak the paths, bring it up
- Spend 15 minutes exploring the UI; it’s intuitive
- Start with a conservative flow (h265, high CRF like 25–26 for safety)
- Test on 10 files, verify playback, then go nuclear
- Come back in a month when your storage bill drops
That’s it. Go forth and compress.