Queue4Download (Q4D): The Complete Setup Guide

If you’ve read my post about fixing my media pipeline, you know Q4D is the glue that holds the whole thing together. It’s the piece that gets completed downloads from a remote seedbox back to your home NAS automatically, so Sonarr and Radarr can do their thing.

The problem is there’s almost nothing written about it. The GitHub repo exists, there’s a small community on r/sbtech, and that’s about it. If you get stuck, you’re mostly on your own. This post is the guide I wish existed when I set it up.

What Is Q4D?

Q4D stands for Queue4Download. It’s a set of scripts and a Docker container that automates pulling completed torrents from a remote seedbox to your home server. It was written by the folks over at r/sbtech and is actively maintained.

The core idea is event-driven transfer: instead of polling the seedbox on a schedule to see what’s done, your torrent client fires a notification the instant a download completes. Q4D hears that notification and immediately starts pulling the file home. No delay, no polling overhead, no missed transfers.

It does this using MQTT — a lightweight publish/subscribe messaging protocol that’s dead simple and works reliably over a WireGuard tunnel.

How It Works

Here’s the full flow from torrent completion to Plex:

  1. rTorrent on the seedbox finishes a download
  2. rTorrent fires a completion hook — a script called Queue4Download.sh that ships with Q4D
  3. That script publishes an MQTT message over the WireGuard tunnel to your home network
  4. The Q4D Docker container on your home server is subscribed to that MQTT broker and receives the event
  5. Q4D uses LFTP over SFTP to mirror the completed file from the seedbox to your local download directory
  6. Sonarr or Radarr, which are watching that directory, detect the new file and import it

The whole thing from “torrent finished” to “file is on your NAS” typically takes a few minutes depending on file size and your WireGuard tunnel bandwidth.

What You Need

Before you start:

  • A seedbox running rTorrent (swizzin is a common choice)
  • A home server running Docker — Unraid, TrueNAS SCALE, OpenMediaVault, Proxmox, a plain Linux box, whatever. If it can run Docker containers, it works.
  • A WireGuard site-to-site VPN between your seedbox and home network (Q4D’s SFTP and MQTT traffic runs through this)
  • Basic comfort with Docker and editing config files

Part 1: Seedbox Setup

Install Q4D on the Seedbox

SSH into your seedbox and grab the Q4D scripts from GitHub:

cd ~
git clone https://github.com/sbtech-community/Q4D ~/.Q4D

The key file here is Queue4Download.sh. This is the script rTorrent calls when a torrent completes.

Configure the MQTT Publisher

Open ~/.Q4D/Queue4Download.sh and set your MQTT broker address. This should be the WireGuard IP of your home server (not the LAN IP — the WG tunnel IP):

MQTT_HOST="172.16.x.x"   # Your Unraid WireGuard IP
MQTT_PORT="1883"

The script uses mosquitto_pub to publish the MQTT message. If your seedbox doesn’t have mosquitto installed, Q4D ships with a compiled static binary you can use instead. Check the repo for the prebuilt binary option — it’s in the releases section and works on Debian/Ubuntu-based seedboxes without any dependencies.

Add the rTorrent Hook

Q4D fires via a completion event hook in rTorrent. Open your .rtorrent.rc and add:

method.set_key = event.download.finished,queue4download,"execute.nothrow=~/.Q4D/Queue4Download.sh,$d.name=,$d.base_path=,$d.custom1="

This tells rTorrent: when any download finishes, call Queue4Download.sh with the torrent name, base path, and label (custom1). The label is important — Q4D uses it to decide where to put the file on your NAS.

Set TypeCodes (Labels)

Q4D uses what it calls TypeCodes to route files to the right destination. The label you set in rTorrent when adding a torrent determines where it ends up on Unraid.

Common TypeCodes:

  • T — TV shows → routes to your TV download directory
  • M — Movies → routes to your movie download directory

So when Sonarr adds a torrent to your seedbox, it labels it T. When Radarr adds one, it labels it M. Q4D sees the label, pulls the file, and drops it in the right place for Sonarr or Radarr to import.

You configure the TypeCode mappings in the Q4D Docker container on your home server.

Part 2: Docker Setup (Home Server)

Pull the Q4D Container

How you deploy this depends on your platform — Unraid’s Docker tab, Portainer, a compose file, or just a plain docker run. The setup is the same regardless. You need:

  • Image: q4d/q4d:latest (check the GitHub repo for the current image name)
  • Network type: Bridge
  • Port: Map 1883 (host) → 1883 (container) — this is the MQTT broker

Container Paths

Map your download directories into the container. The host paths will vary depending on your setup — adjust them to wherever your NAS or server stores incoming media:

Container PathHost PathPurpose
`/media/tv``/your/downloads/tv`TV download landing zone
`/media/movies``/your/downloads/movies`Movie download landing zone
`/config``/your/appdata/q4d`Q4D config and logs

On Unraid these would typically be under /mnt/user/. On TrueNAS SCALE or a plain Linux box they’ll be wherever you’ve mounted your storage.

Configure Q4D

In the Q4D config (in your /config directory), set up:

SFTP_HOST=172.16.x.x        # Seedbox WireGuard IP
SFTP_USER=yourseedboxuser
SFTP_KEY=/config/id_ed25519  # SSH key for auth (see below)

TYPECODE_T=/media/tv
TYPECODE_M=/media/movies

Also run the q4d-monitor container alongside q4d — it provides a web UI to see transfer status and history.

Part 3: SSH Key Authentication

This is where most people get tripped up. Q4D uses LFTP over SFTP to pull files from the seedbox. LFTP needs to authenticate, and you want it to use SSH key auth — not password auth.

Generate a Key Inside the Container

First, get a shell inside the Q4D container:

docker exec -it q4d bash

Generate an ed25519 key:

ssh-keygen -t ed25519 -f /config/id_ed25519 -N ""
cat /config/id_ed25519.pub

Copy that public key.

Add the Key to Your Seedbox

SSH into your seedbox and add the public key to authorized_keys:

echo "ssh-ed25519 AAAA... your-key-here" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Test It

From inside the Q4D container, verify the connection works:

lftp -u yourseedboxuser, sftp://172.16.x.x

If it connects without asking for a password, you’re good.

Why this matters: If your seedbox was previously set up with password auth and you later harden SSH (which you should — password auth over the internet is bad), Q4D will silently break. File transfers just stop. No obvious error unless you’re watching logs. Always use key auth from the start.

Part 4: Connecting Sonarr and Radarr

Once Q4D is dropping files in your download directories, Sonarr and Radarr need to be told about it.

Remote Path Mappings

This is the step that trips people up most. Your torrent client (rTorrent) reports file paths on the seedbox. Sonarr and Radarr need to know how to translate those seedbox paths to the local paths where Q4D dropped the files.

In both Sonarr and Radarr, go to Settings → Download Clients → your rTorrent client → Remote Path Mappings:

Host: your-seedbox-hostname
Remote Path: /home/yourusername/    (or wherever rTorrent stores active downloads)
Local Path: /downloads/tv/          (or wherever Q4D dropped it)

You may need two mappings — one for the active download path and one for the completed/seeding path. rTorrent reports whichever path the file is in at the time of the import event.

One heads-up: Radarr sanitizes usernames in log output. If you see /home/(removed)/... in Radarr logs and try to use that as your remote path, it won’t work. Check the actual filesystem path on your seedbox and use that.

Known Gotchas

WireGuard tunnel goes down. If the WG tunnel between your seedbox and home network drops, MQTT events stop arriving. Downloads pile up on the seedbox and nothing syncs. Q4D doesn’t queue up missed events — when the tunnel comes back, you may need to manually retrigger transfers for anything that completed while the tunnel was down. Some routers (including the UniFi Dream Machine Pro) don’t auto-restart non-default WireGuard interfaces on reboot — worth checking your router config.

Container needs restart after tunnel reconnect. On bridge-networked Docker containers, if the WG tunnel drops and comes back, the container’s routing can get confused. If transfers mysteriously stop working after a tunnel blip, restart the Q4D container first.

SSH hardening breaks LFTP. Covered above but worth repeating: if you disable password auth on your seedbox after Q4D is already set up, LFTP breaks. Set up key auth before you harden SSH, or fix it immediately after.

TypeCodes are case sensitive. T and t are different. Make sure the labels Sonarr and Radarr set on torrents match exactly what you’ve configured in Q4D.

Mosquitto binary on newer Debian. If your seedbox is on a newer Debian/Ubuntu and you’re having trouble with the mosquitto_pub binary included with Q4D, check the repo’s releases section — there are updated static binaries.

The End Result

When it’s all working, the experience is pretty satisfying. Someone requests a show through Seerr, Sonarr picks it up, the seedbox grabs it, and within a few minutes of the download finishing the file is on your NAS and Sonarr is importing it. You don’t touch anything.

Q4D is a small piece of the puzzle but it’s a critical one. Without it you’re either manually copying files or running some polling script that checks the seedbox every few minutes. Neither is great. The event-driven approach Q4D uses is the right way to do it.


This is part of an ongoing series on self-hosted media infrastructure. Previous post: How I Fixed My Broken Media Pipeline and Built a Monitoring Stack in One Day

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.