⚡ nzbfast

The fast Usenet downloader - user manual

1 · Welcome

nzbfast downloads from Usenet as fast as your line, your providers, and your machine allow - and usually that means as fast as your line. It is a single self-contained program: the engine, a web dashboard, a poster-wall media browser, a built-in indexer, realtime preview, native PAR2 repair, and native RAR extraction are all inside one executable. There is nothing else to install.

What makes it fast is architecture, not tweaks:

Measured against the field on identical hardware, jobs and providers, nzbfast has finished a 190 GB download in around 5 minutes on a 10 GbE line, with the leading alternatives 30–220% behind on the same tests where they completed them at all. The figures are in §3.

2 · Quick start

macOS

  1. Open nzbfast-<version>-macos.dmg and drag NzbFast into Applications (universal: Apple Silicon + Intel).
  2. First launch: macOS warns that nzbfast isn't Apple-notarized yet. Right-click the app → Open, or open System Settings → Privacy & Security, scroll down, and click Open Anyway. This is a one-time step.
  3. The app window shows the dashboard with a welcome card. Click it and add at least one Usenet server (host, port 563, username, password). You can add more later in Settings.
  4. Drop an .nzb anywhere on the dashboard, or just double-click .nzb files in Finder. Downloads land in ~/Downloads/nzbfast. Quit from the menu; downloads resume where they left off.

Prefer no app? The plain zip (binary + Start nzbfast.command launcher, same engine) still works as before. The steps are below, under "From a terminal".

Windows

  1. Run nzbfast-<version>-windows-x64-setup.exe. It installs for your user only (no administrator password). Because this release is not yet code-signed, SmartScreen may show "Windows protected your PC". Click More infoRun anyway.
  2. nzbfast lives in the system tray: double-click the tray icon (or use Open Dashboard in its right-click menu) to open the dashboard, then add your Usenet server from the welcome card. The tray menu also has Pause/Resume, your downloads folder, and Quit.
  3. Double-clicking a .nzb file queues it. Windows Defender may ask once to allow local network listening. Allow it.

Prefer a portable copy? The -windows-x64.zip still works: unzip anywhere and double-click nzbfast.exe (or Start nzbfast.bat) for the terminal wizard.

From a terminal (any platform)

nzbfast setup            # interactive server setup (writes config.local.json)
nzbfast serve --open     # start the daemon and open the dashboard
TipAlready run SABnzbd or NZBGet? Skip typing credentials: Settings → Usenet servers → Import from SABnzbd / NZBGet… finds your existing installation and copies its servers over. There is also nzbfast import-sab on the command line.

Your API key

On a genuinely new install, nzbfast makes itself an API key the first time the daemon starts, and prints it once in a banner just under the dashboard address. From then on every request needs that key, so the dashboard and the API are not open to everything that can reach the machine.

What you do with it depends on how you started nzbfast:

The key is kept in a file called apikey beside your config file, so it stays the same across restarts and you can read it back whenever you need it. On macOS and Linux that file is readable only by the account that runs nzbfast. It is also in the daemon's own output, so the dashboard's Log card has it if the terminal has scrolled away.

Upgrading changes nothing.An install that already exists is left exactly as it was, key or no key. A key is only ever made on a first run - one with no dashboard settings and no saved queue - because a key appearing under a working install would lock out every Sonarr, Radarr and phone app you had already connected, on a restart you never connected to a settings change.

To use a key of your own instead, type it into Settings → Security; it applies at once. That panel changes the key but never shows the current one, so read the apikey file if you need the generated value back. To run with no key at all, because something in front of nzbfast already handles sign-in, start it with NZBFAST_OPEN=1 in the environment. nzbfast then stays open and says so plainly at startup.

Which machines can reach the daemon at all is a separate choice: serve --bind. The default is 0.0.0.0, meaning every network interface, because a NAS box, a phone, and a Sonarr on another computer all have to be able to connect. --bind 127.0.0.1 narrows it to the machine nzbfast runs on, which is what you want on a single desktop where nothing else needs access.

3 · How nzbfast works

A quick vocabulary so the rest of the manual reads easily:

TermMeaning
Provider / serverA Usenet service you have an account with (Newshosting, Eweka, XS News…). Each allows some number of simultaneous connections.
BackboneThe infrastructure behind a provider. Several brands often resell the same backbone, useful to know because two providers on one backbone miss the same articles. See Server diversity.
NZBA small XML file listing the articles that make up a post. This is what you feed nzbfast.
PAR2Recovery data posted alongside a release. nzbfast verifies against it during the download and repairs automatically when articles are damaged or missing.
Store-mode RARMost releases are packed into RAR volumes without compression. nzbfast recognizes this and writes the inner file directly to its final location while downloading, with no unpack step afterwards.

The pipeline runs download → decode → verify → extract concurrently. The Pipeline card on the dashboard shows all three lanes moving at once. When the last byte arrives, verification is already done and the file is already extracted; a typical job's "post-processing" time is zero. If repair is needed, only then are volumes materialised to disk, repaired in place by the native GF(2¹⁶) engine (renamed or byte-shifted obfuscated data is found and adopted by a sliding block scan), and re-extracted, all automatically.

Interrupted downloads (crash, power loss, kill -9) resume from the article journal: bytes already on disk are never fetched twice. The journal records where every article's bytes physically landed (even bytes that were direct-extracted into the final file), so a resume rebuilds from local disk and re-verifies everything it restored against the PAR2 block map before trusting it.

How that compares

Measured against SABnzbd 5.0.4 and NZBGet 26.2 on the same machine, the same providers and the same NZBs, timed to a usable file (download, verify, repair and extract all included), because that is when the job is actually done:

Job sizenzbfastNZBGet 26.2SABnzbd 5.0.4
7 GB13.7 s+26%+39%
35 GB67 s+61%+325%
87 GB272 s+36%+160%
190 GB9 m 00 s+30%+111%

The gap is the post-processing the others still have to do after the last byte lands. Both competitors were tuned for the comparison, not left on defaults. SABnzbd in particular ships with request pipelining off, which costs it dearly, so it was switched on.

Two differences matter as much as the times:

Crash resume, measuredKill a download mid-flight (kill -9 at 15 GB of a 34.5 GB job) and the resume re-fetches ~0.3 GB (only the articles genuinely in flight at the kill) against NZBGet's 0.2 GB in the same test. This used to be a loss we published (15.3 GB re-fetched, when the journal couldn't account for direct-extracted bytes); the placement journal fixed it: the resume restores those bytes from the local output files and re-verifies every restored byte against the PAR2 block map before trusting it. Every scenario we lose is published alongside the wins, with the full method and raw numbers.

4 · The dashboard

Open http://localhost:6789 (or your machine's address from another device; the phone layout adapts automatically). Everything updates live, once a second. The cards, top to bottom:

Header bar

Throughput

Live MB/s with a scrolling chart; the dashed watermarks mark this session's high/low, the faint line is a moving average. Below it, a histogram shows how the session's speed samples distribute: typical vs peak. Widen the window and the charts show more history (up to an hour).

Stat tiles

Downloaded this session, queue depth, completed/failed counts, session peak speed.

Resources: one machine, four ceilings

CPU, RAM (against nzbfast's memory budget), disk write rate and network on one normalized chart, with real values in the legend and a low-disk warning. No other NZB client shows you this; it exists to prove a point: nzbfast will max your line, not your machine.

Pipeline: stages overlap

Three lanes: download, verify (PAR2 blocks checked), extract. On a healthy job all three move together.

Providers

Per-server live rate, connection utilization, share of traffic, session GB, and a lifetime article-completion score (colored when a server drops below 98%). A stacked area chart shows each provider's contribution over time. Rows re-order by live performance every 10 s (configurable in Settings → Interface) so your fastest provider is always on top.

Queue

Browse index

Search everything the built-in indexer has catalogued from your watched groups (see Automation) and download with one click, no external indexer needed. The status line shows scan progress; Scan now forces a pass.

Watchlist

Add titles by name, including ones not posted yet. When a matching release appears in the index it is grabbed automatically, with quality preferences and upgrade rules (a better copy replaces a worse one).

History

Recent downloads, one row each. Failed jobs offer Retry (resumes from the journal). Encrypted archives show a 🔑 unlock control: enter the password and the job finishes in place. The verify-health strip charts bad PAR2 blocks per download: a rising tail means articles are arriving damaged. Each row's drawer says who added the job and has the same Download .nzb button as the queue - handy for downloading a release again somewhere else, or attaching the .nzb to a problem report.

The card lists ten downloads by default and the rest are one click away, on the ▤ button. Status, location and the reason a job failed live behind a click on the row itself, so the common case - what finished, how big, when - stays readable without scrolling. Drag the card's bottom edge to make the list scroll at a height you choose instead. History rows in Settings → Interface changes the ten; because it is a property of the daemon rather than of your browser, it applies to every device looking at this install. Colour History names, beside it, tints finished names green and failed ones red; turning it off leaves the names plain, and the coloured dot and the row's own details still say which is which.

Data usage

Per-provider daily bars and Today / 7-day / 30-day totals, essential for metered and block accounts. Block accounts show lifetime usage against their size.

Log, System benchmark, Connection tuning, Server diversity

An in-page log viewer, and the three self-measurement tools described in Performance tools.

5 · Adding downloads

MethodHow
Drag & dropDrop one or more .nzb files anywhere on the dashboard.
Watch folderSet a folder in Settings; any .nzb saved into it is picked up within 5 seconds and moved to the Trash, and an open dashboard announces each pickup by name ("Picked up … from Downloads"), so a file leaving the folder is never a mystery. Prefer to keep your files? Turn on Keep .nzb files after pickup (see §9). Point your browser's download directory at it for one-click grabs from indexer sites.
From a URLPaste an NZB link (API mode=addurl, or via any connected app).
nzblnk: linksPaste an nzblnk: link anywhere on the dashboard, or drag it in. If you installed from the macOS DMG or the Windows installer you can also click one straight from a board. See nzblnk links below.
Browse indexClick any complete release in the Browse card.
Watchlist / RSSAutomatic; see Automation.
Sonarr/Radarr etc.They send grabs straight to the queue; see §11.
Command linenzbfast get file.nzb downloads without the daemon.

Categories, priorities, passwords

nzblnk links

Some boards, mostly German and Dutch ones, publish an nzblnk: link instead of an NZB file. The posting is obfuscated, so there is no filename anyone could link to. The link carries a header, h=, which is a search key rather than a location, plus an optional title t=, password p= and newsgroup g=. Something has to go and find the posting first.

nzbfast looks the header up in its own index to begin with, which needs no network at all, and only if that misses does it ask the search indexers you have configured (Settings → Search indexers, §9) under the same daily budgets and backoff as any other search. The title becomes the job name and the password is applied to the job automatically.

6 · The poster wall

Click 🎬 wall in the header. The wall turns your index into a media browser: every recognized film and TV release as a poster tile with rating, year, genres, cast and synopsis: your newsgroups, browsable as a catalogue.

7 · Preview & verify

You don't have to wait for a download to finish to know it's the right file. Open it while it downloads, check the content, language and quality are what you expected, and cancel early if they aren't, instead of finding out after the full download.

Player noteVLC, IINA, mpv and Infuse all open /stream URLs. To check from another machine use your machine's LAN address in place of localhost.
Auth noteWith an API key set, opening a parked library entry over /stream/<id> requires a per-job token (?t=…): players can't send API keys, so the /m3u handoff and the .strm pointer embed it for you; minting it (/m3u) requires the key. Plain byte-serving of an already-active download stays open, and keyless installs behave as before.

8 · Usenet servers

Settings → Usenet servers is the full editor: add, edit, remove, reorder, and switch any server in or out of the pool. Each server has:

FieldNotes
Host / portUse SSL port 563. TLS costs nothing measurable: nzbfast always encrypts.
Username / passwordStored locally in config.local.json, never shown back to the browser. Leaving password blank on edit keeps the stored one. Passwords are obfuscated on disk, not encrypted.
ConnectionsPer-server simultaneous connections. Use Connection tuning (§13) to find each provider's sweet spot rather than guessing high.
Level (tier)0 = primary; higher levels are fill servers, only asked for articles every lower level missed. Put unlimited accounts at 0, block accounts at 1+.
Block size (GB)For block (pay-per-GB) accounts: nzbfast tracks lifetime usage against this and stops using the server when spent (warning at 85%).
Every byte is billedTurn on for a metered account. Your downloads use the server exactly as before; what stops is nzbfast sending it traffic of its own - the automatic connection tuner, the system benchmark's network leg, and header scans for the built-in index all skip it. Independent of the level and of the block size, because a metered account can be your only provider and an unlimited one can sit at level 2. Off by default. The manual Test in Connection tuning (§13) still works on a flagged server and asks first, since that one is you choosing to spend.

Leave a little headroom under your account's connection cap. Setting connections a shade below the cap costs nothing: throughput flattens out well before the last connection or two, and Connection tuning (§13) usually settles below it anyway. Those spare slots are what let a second device, another client, or a retry after a dropped socket still get in, instead of being refused while this one holds every slot.

How your provider passwords are stored

Provider passwords in config.local.json are obfuscated, not encrypted. They are stored as obf1: followed by an encoded form, so the file does not read as plain text if it appears in a screenshot, a forum post, a bug report, or on a screen someone else can see.

Be clear about what that does and does not buy you:

For comparison, NZBGet and SABnzbd both store provider passwords as plain readable text in their config files. We think obfuscation is a small improvement on that, not a security feature.

Why not the system keychain? macOS Keychain, Windows Credential Manager and the Linux secret services would give real protection, and we may revisit it. Two things stop us today. Keychain access is tied to application identity, and nzbfast is not code-signed yet, so the prompts and the behaviour after every update are poor. And a large share of installs are Docker, headless servers and NAS boxes where no keychain exists at all, which would leave two different storage paths to keep correct. A single well-understood format that behaves the same everywhere is, for now, the better trade.

Two further per-server options have no dashboard control yet: add them by hand to that server's entry in config.local.json (see §17) and restart.

KeyNotes
bind_ipBind this server's outgoing connections to a specific local address, for multi-homed boxes and VPN split tunnels. The address family also picks the target family: a v4 bind connects to the server's v4 address.
socks5Send this server's NNTP traffic through a SOCKS5 proxy: host:port, or user:pass@host:port. The hostname is resolved by the proxy, so there is no local DNS leak.
RecommendationTwo providers on different backbones beat three on the same one. Run Server diversity (§13) to see which of your providers actually diversify your coverage and which are redundant copies of each other.

9 · Settings reference

Nearly everything is configurable from the dashboard, under ⚙ Settings; the four exceptions are listed at the end of this section. Values marked live apply immediately; restart values apply on the next launch. Every change made here is persisted to settings.json and survives restarts (UI values win over command-line flags).

Speed & scheduling live

SettingWhat it does
Speed limitCap in bytes/sec (50M, 1G, 0 = unlimited). Remote apps may send percentages; set Line speed so they translate correctly.
Auto speedRTT-governed cap that yields to other household traffic and re-expands when the line is quiet.
Auto-defer slow downloadsA job stuck on one slow server while others wait is moved to the back of the queue (progress kept). See §13.
Prefetch on idle serversServers useless to the active job start the next queued one. See §13.
Check for updates / Update check URLNotify-only update notices. See §14.
Line speedYour connection's rated speed, enabling percentage limits from SABnzbd-compatible apps.
Weekly scheduleRow editor for time-of-week rules: pause, resume, or set a speed limit at given days/times (local time). E.g. limit to 20 MB/s on weekdays 9–17, unlimited otherwise.

Next download live

Connections (per server), window (pipelining depth per connection), decoders (parallel decode threads). Sampled when each job starts. Defaults are right for most lines; use the tuning tools before raising blindly.

Checking while downloading picks how much is verified as the data arrives. Full confirms every PAR2 block with MD5. Fast (the default) claims blocks by CRC32 instead, which is 2-3x quicker on a slow CPU, and still verifies every article's own checksum. Lean also skips those article checksums once PAR2 covers a file, so damage surfaces a moment later, at its block. In all three the final settle pass and any repair use full MD5, and a download with no PAR2 files keeps its article checksums.

Disk & quota live

Minimum free space (pause new jobs below it; 2 GB by default, so a disk never fills to zero, and 0 turns it off), download quota per day or month (UTC; Force jobs bypass), memory limit, the engine's RAM budget (default: ¼ of RAM, clamped; raise it on a big-RAM box for maximum speed on huge jobs, and see what low memory costs before lowering it) restart.

Move completed to: after unpack, cleanup and renaming, finished downloads move here - a NAS share, a media drive, wherever your library lives. The category layout is preserved (a job that finished under tv/ lands under tv/ at the destination), and history follows the move, so connected apps import from and delete at the new location. If the destination is unreachable when a job finishes (share offline, out of space), the files stay in the download folder and the job still completes normally. Empty = off. Per-category destinations route specific categories elsewhere (tv=/Volumes/NAS/TV, movies=/Volumes/NAS/Movies); each listed path is that category's folder, so no extra category subfolder is created inside it. Unlisted categories follow Move completed to.

Nested archive depth (default 5) is how many archive-in-archive layers are unpacked automatically: a RAR set containing a 7z containing another RAR is normal on Usenet, and nzbfast follows the chain without a second pass. At the limit the deepest archive is simply left in place, unpacked no further, and the download still completes. Raise it only for unusually deep releases.

Naming & cleanup live

Rename finished downloads (on by default) gives the folder and the main file a clean, informative name: a film becomes Example Movie (2024), TV keeps Show - S01E02. Obfuscated or unrecognized names are left exactly as posted rather than guessed at.

SettingWhat it does
Include resolutionAdds 1080p, 2160p… to the name. On by default; the other four tags are off.
Include video codecx265, x264, AV1
Include audio codecAtmos, DTS-HD, AC3
Include sourceBluRay, WEB, REMUX
Include release groupThe -GROUP tag at the end.
Remove junk filesOn by default. Deletes leftover .par2, .nzb, .sfv, .nfo and sample clips from finished film/TV folders. Never the video or its subtitles.
Keep only the media fileOff by default, and destructive: permanently deletes everything in the folder except the video(s) and subtitles. Every episode of a season pack is kept. Supersedes Remove junk files when both are on.
Keep the other words in the nameOn by default. Sport, races and other events are often one title repeated all season, and only a word or two apart - "Round11 Hungary Race" against "Round11 Hungary Qualifying". Keeping those words is what stops a whole season collapsing into the same name. Only applies where the name could not be tidied up any other way, so ordinary films and TV episodes are untouched.

The whole group runs after repair and unpack and before Move completed to, and is skipped entirely for a job still waiting on a password. Both delete steps apply only to releases recognized as film or TV: a software payload or an unclassifiable (obfuscated) set is never swept.

Deleted files go to the Trash decides what "delete" means above. With it on, cleanup moves files to the system Trash or Recycle Bin, so a wrong guess about what was junk can be undone; with it off they are deleted outright. It is on by default on macOS and Windows, where the Trash is somewhere you can see and empty, and off by default on Linux, where it usually is not.

On a NAS or in a container, leave this off. When your downloads are on a different disk from your home directory - which is the normal arrangement on Unraid, Synology, a seedbox or any Docker install with a mounted share - the Linux trash rules do not use a desktop Trash at all. They create a hidden .Trash-1000 folder (the number is your user id) at the top of the download disk and move the files there instead. Nothing shows you that folder, nothing empties it, and the space it holds never comes back.

If you ran an earlier version of nzbfast on Linux with this on, look for that folder at the root of your download share. It is safe to empty: everything in it is a file cleanup already decided you did not want. nzbfast will not empty it for you, because it is on your disk and yours to judge.

Folders & processing

Download folder restart, watch folder, post-processing script (run after every job with SABnzbd-compatible arguments and SAB_* environment; existing SAB scripts work unchanged), cleanup extensions (junk files deleted after completion), Smart Folders and TV filing (see §10).

Keep .nzb files after pickup (off by default) leaves the original .nzb in the watch folder after it is queued, instead of moving it to the Trash - for collectors, and for handing the file to someone when a download misbehaves. A kept file is remembered, across restarts too, and is not queued again; re-save it to download it again. Whichever you choose, every job's drawer has a Download .nzb button, so a copy of any job's .nzb is never more than a click away.

Indexing live

The built-in indexer is off by default. It finds posts made under a real filename, and a large and growing share of Usenet is deliberately posted without one: random subject, random filenames inside, dropped into a catch-all group. The real name lives only in an NZB the uploader publishes elsewhere, so it was never on Usenet for any scanner to read. Measured on our own index, 14.8 million scanned posts produced about 31,000 browsable releases, roughly one in five hundred. Keep using commercial indexers, and add them under Settings → Search indexers so you can search them from the wall. Turn this on if you follow specific groups where people still post under real names, or you want to see what your provider actually carries. With the switch off nothing is scanned or fetched, no database is created, and the wall, Browse, the watchlist and the newznab feed are hidden.
SettingWhat it does
Built-in indexerThe master switch, off unless you turn it on. Off means no scanning, no metadata lookups, no availability sampling and no newznab feed; an index already on disk is kept (there is a delete button) so switching back on resumes rather than rescanning.
GroupsNewsgroups the built-in indexer scans (e.g. alt.binaries.teevee).
Scan intervalSeconds between passes (default 900).
Backfill articlesHeaders fetched on a group's very first scan.
Deepen per scanEach pass also indexes this many older articles, growing your searchable history in the background until Max age is reached (default 200,000 per pass ≈ tens of millions of articles per day of uptime).
Max ageIgnore posts older than this (90d, 6m, 2y), capping index size and scan time.
Trim to the age windowOn by default. Also deletes already-stored releases once they age past Max age, so the index holds roughly that window instead of growing forever. Off = only new posts are gated, and what is already stored stays. Dead junk fragments (hidden, still incomplete after a week) are reaped either way.
Ingest gatesJSON rules filtering what enters the index: kinds (obfuscated junk is dropped by default), year/resolution/language, size bounds.
Scan now / deep rescanRun a pass immediately; with a depth, re-scan that many recent headers.
OMDb key / metadata refresh / wipeWall enrichment controls (§6). Wipe rebuilds the database from scratch: the recovery path if it is ever corrupted.
Pre feedOff unless you turn it on. Plenty of uploads are posted with the name taken out, so a scan has nothing to read. Public relay channels announce the real name, which is the one open way to match those posts up. Turning this on keeps a connection open to an IRC network and listens: nothing is ever sent, and no account is created. Needs the indexer on, since a feed with nowhere to store what it hears is a socket held open for nothing.
Relay server, Relay channelsThe IRC network carrying the announcements (host or host:port) and the comma-separated channels to listen in. A change takes effect on the next connect, so toggle the feed off and on to apply one immediately.
Name by correlationThe live public relays carry no filenames, so most obfuscated posts cannot be matched directly. What an announcement does pin down is when a release appeared and how big it is. This compares announcement timing and size against unnamed posts and, when they fit, suggests the real name on Browse. A suggestion is marked as one, takes your click to apply, and never renames files on disk.
Apply strong matches automaticallyOff by default, and strict when on: the size must agree tightly, no other announcement may fit nearly as well, and the announcement must pick this post back when checked the other way round. Applied names change only how a release is shown, are marked as inferred, and come back off on their own if a finished download proves one wrong. Everything weaker stays a suggestion.
Announcement historyThe live feed only hears announcements made after it is switched on. This fetches roughly six months of past ones from a public pre database, politely and once, so posts already in the index can be matched too. Runs in the background for half an hour or so.

Library, Security, Interface

Library: categories treated as instant library entries + re-check interval. Security: the full API key (everything) and the NZB key (add-only, safe to give indexer sites), both rotatable live. Either box replaces the key it belongs to as soon as you leave the field, and leaving a box blank keeps the key it already has. The API key also has Show, which reveals and copies the current key so you can paste it into Sonarr, Radarr or NZB360 whenever you get round to it, and Create new, which mints a replacement - the old key stops working immediately, so anything already connected has to be given the new one. Both are gated on the API key itself: the add-only NZB key cannot read it, which is the whole point of that key being add-only. For where the key comes from on a new install, see §2. Interface: click sounds, desktop notifications on completion, provider re-sort interval.

Speed units live decides how every speed in the dashboard is shown: megabytes (MB/s, the download-manager norm, the default) or megabits (Mb/s, how ISPs quote line speeds). File sizes stay in bytes either way. This is a property of the daemon, not of your browser, so it applies to every device looking at this install.

Advanced: the tuning knobs behind the obvious ones

Six settings that have no command-line flag. Each one now has an advanced row on the settings card that owns it, and each is also settable through the API (§16), e.g. /api?mode=config&name=verify_mode&value=lean&apikey=…. Like every other setting they persist to settings.json.

NameWhat it does
verify_modefull | fast | lean (default fast). lean is the slow-CPU boost: like fast, but it also skips the per-article yEnc CRC once PAR2 covers a file, leaving one CRC32 layer instead of two. PAR2-less downloads keep their article CRCs, and end-of-job verification and repair are unchanged either way. The Checking while downloading picker above is this setting.
auto_retry_minsCooldown before the one automatic retry a first failure gets when articles were missing (default 20). Propagation lag is a real cause of missing articles and clears on its own; the journal makes the rerun fetch only what is still absent. Password and takedown failures never qualify.
index_scan_parHow many groups the indexer scans in parallel (default 3, clamped 1-8).
oracle_sampleIdle STAT budget for the availability oracle (§13), probes per hour per server. Default 300, max 3600, 0 disables sampling entirely.
predb_max_rowsHow many pre announcements the feed table keeps (default 250000, clamped 10000-5000000). The hourly prune trims to this number and the historical seed import refuses to start when it would push past it, so an import can never add rows the next prune deletes.
predb_seed_daysHow far back a historical seed import reaches when it is started without a window of its own (default 180 days, maximum 366). A longer window is more requests to the pre source, which is paced at one every two seconds.

10 · Automation

Watchlist

The simplest automation: add a title on the dashboard, set quality preferences, done. New releases are grabbed as they appear in your indexed groups; better-quality copies upgrade earlier grabs; a calendar view shows what's coming.

RSS feeds

Settings → RSS: any newznab/indexer RSS URL with per-feed interval, category and filter rules (title patterns, size bounds). Matching items are downloaded automatically.

Smart Folders

Rules evaluated when a job is added: match by pattern/keywords and size, assign a category (first match wins). With TV filing on, finished TV episodes are renamed and filed as Show/Season 01/Show - S01E02.mkv, ready for Plex or Jellyfin without an external tool.

Scheduler

The weekly schedule (see §9) automates pause/resume/speed by time of day.

Scripts

A post-processing script receives SABnzbd's positional arguments and SAB_* environment variables: the large ecosystem of SAB scripts runs as-is.

11 · Sonarr, Radarr & friends

nzbfast speaks the SABnzbd API natively, so every *arr works out of the box, and it can act as their indexer too.

As the download client

  1. In Sonarr/Radarr: Settings → Download Clients → add SABnzbd.
  2. Host: your nzbfast machine · Port: 6789 · API key: your full API key (where to find it: §2).
  3. Category as desired (e.g. tv / movies). Test → green check → Save.

Queue, history, per-job status, "remove & delete", retry and category routing all behave as the *arrs expect.

As an indexer (newznab)

  1. Settings → Indexers → add Newznab.
  2. URL: http://<host>:6789/ · API path: /api · key: your API key.
  3. nzbfast serves caps, search, tvsearch and movie queries from its own index of your watched groups, and /getnzb/<id> hands back the NZB.
Switch the built-in indexer on first (Settings → Indexing). It is off by default, and while it is off this facade answers every query with <error code="101"> rather than an empty result, so a mistake shows up when you add the indexer instead of weeks later.

Why bother? A self-hosted indexer of exactly the groups you care about: no accounts, no API hit limits, retention as deep as you let it scan. It is an addition to your usual indexers rather than a replacement, because it only finds what was posted under a real filename.

12 · Phone & remote apps

nzbfast implements both major remote-control protocols, so nearly every mobile/tablet app works. Pick whichever protocol your app supports:

Apps that speak NZBGet (nzb360, LunaSea, NZB Unity…)

Field in the appValue
TypeNZBGet
Host / portyour machine : 6789
Usernameanything (e.g. nzbfast)
Passwordyour API key

The full JSON-RPC surface these apps use is served: status, queue with reorder/pause/delete, history, add-NZB, speed limit, pause/resume, log.

Apps that speak SABnzbd

Field in the appValue
TypeSABnzbd
Host / portyour machine : 6789
API keyyour API key (or the NZB key for add-only access)

The dashboard on your phone

Just open http://<machine>:6789 in a mobile browser. The whole dashboard and wall have a touch layout. The Settings → Remote access panel shows the exact URLs and a QR code to scan.

Reaching nzbfast from outside your home

There is no login page, and that is deliberate. A session-cookie login is a security surface to maintain forever, and it would still be the weakest lock on anything facing the open internet. nzbfast authenticates with your API key instead, and it takes that key in a request header as well as in the URL (X-Api-Key, or Authorization: Bearer) - which is what lets something in front of it handle the sign-in properly.

The simplest answer is not to publish it at all. Install Tailscale on this machine and on your phone and both join one private network: nothing is exposed, no router or certificate work is needed, and Settings → Remote access prints a works-from-anywhere address as soon as it sees Tailscale running. Prefer this unless you specifically need a public domain.

nzbfast can also serve HTTPS itself. Point Settings → Security → HTTPS certificate / HTTPS private key at a PEM certificate and its key (or start with --tls-cert cert.pem --tls-key key.pem), restart, and the dashboard and API answer on https:// instead of plain HTTP - one listener, one scheme. Use the certificate your domain already has (for example from Let's Encrypt via certbot), or a self-signed one for the LAN, which browsers accept after a one-time warning. A bad or expired certificate refuses startup with the file named, so the mistake is visible where you made it; renew by replacing the files and restarting. Native HTTPS encrypts the traffic but does not add a sign-in, so keep the API key set.

If you need a public domain, put a reverse proxy in front, give it the certificate, and let it do the authentication. Start nzbfast with --bind 127.0.0.1 so the proxy is the only way in, and point the proxy at http://127.0.0.1:6789:

# Caddy
example.com {
    reverse_proxy 127.0.0.1:6789
}

# nginx
location / {
    proxy_pass http://127.0.0.1:6789;
    proxy_set_header Host              $host;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Layer on whatever your proxy offers: basic auth, a forward-auth service such as Authelia or Authentik, or client certificates. One thing catches everybody - Sonarr, Radarr and the phone apps cannot complete a browser login, so leave them a way past it. Most proxies can admit a request carrying a valid X-Api-Key header and challenge everything else.

Do not simply forward port 6789 on your router. Without a certificate configured the dashboard speaks plain HTTP, so your API key and everything you do with it would cross the internet readable by anyone on the path, and an install with no key set at all is open to whoever finds it. If you forward a port regardless, set an API key first and turn on HTTPS.

13 · Performance tools

System benchmark

One click measures your three ceilings: network throughput (a real 8-second multi-connection probe), CPU verification rate, and disk write speed. It leads with the answer: your expected maximum download speed and which ceiling is the limit. The shortest bar is your bottleneck; the others show their headroom. Schedule it (6-hourly → weekly) and every run is logged to a history table, so you can see when your provider, ISP or hardware changed behavior. Scheduled runs only happen while the queue is idle.

Connection tuning

Measures one provider at rising connection counts and recommends the setting: more sockets help until the provider or your line saturates, and some providers punish over-asking. Test all compares every provider, then bursts them all together to check the pool saturates your line.

Server diversity

STAT-samples articles across ages on every server and clusters providers by shared gaps: providers with ~100% shared missing articles are the same backbone (redundant for recovery); independent ones genuinely extend your coverage. Ends with a plain-language recommendation.

Automatic queue intelligence

The availability oracle

Takedowns are the main reason a Usenet download fails, and they are predictable: the same release goes missing on one backbone while another still has it. nzbfast keeps a small ledger of what your own providers actually answered for, and spends a tiny idle budget of STAT probes (a few hundred an hour per server, never during a download) to keep it current. It never downloads payload to find out.

What you get from it:

The verdict is a prediction from evidence, not a guarantee. For a hard answer on one NZB, nzbfast check (§15) counts the actual articles.

Memory budget: what low memory costs

All engine caches share one budget (default ¼ of physical RAM, clamped to 256 MB–16 GB). Set it explicitly with Memory limit in Settings, or --mem-limit on the command line.

nzbfast is built to soak your network and your disk at the same time, and RAM is what lets it do both in one pass: articles are decoded, verified and written straight to their final offsets, so archive volumes need never touch the disk at all. Starve it of memory and nothing breaks: every cache has a spill path, and the engine degrades to more disk I/O rather than swapping or failing. But that spill is not free, and on big jobs you can measure it.

Measured on one machine and one line (M1 Ultra, 10 GbE), same files at each budget. Every run produced a correct, fully verified, extracted result:

Job sizePlenty of RAM2 GB budget
≈ 8 GB machine
1 GB budget
≈ 4 GB machine
256 MB budget
≈ 2 GB NAS
7 GB15 s15 s15 s15 s
35 GB65 s70 s70 s65 s
87 GB148 s206 s +39%196 s +32%180 s +22%
190 GB330 s427 s +29%402 s +22%411 s +25%

Peak memory tracks the budget, not the job: that 190 GB download completes in about 1.1 GB of RAM. What you trade for it is time, and only on large jobs.

RecommendationGive nzbfast roughly 2 GB of budget per 100 GB of the largest job you download, and leave the default alone otherwise. ¼ of RAM is already the right answer on most machines. In practice: 4 GB RAM covers jobs up to ~35 GB at full speed; 8–16 GB keeps 100 GB-plus jobs there too; a 2 GB NAS will finish anything you throw at it, but treat it as a background downloader rather than something that will saturate a fast line.

On a small NAS, also drop Connections (2–4) along with the budget. At a 256 MB budget and 2 connections, peak memory stays near 190 MB, comfortably inside what a 2 GB NAS has spare. Be aware that at that point the connection count, not the memory, is what limits you: the same 35 GB job took 286 s instead of 65 s. That is the honest shape of the trade: it will always finish, and finish correctly; it just won't soak the line.

Benchmarks are re-run for each release; method and per-machine figures are published alongside the results.

14 · Updates

Updating without losing your settings

One rule covers every install: an update replaces the program, never your settings. Everything you have configured - servers, paths, the API key, the queue - lives in a handful of files in one folder (§17), and no installer, image pull or package upgrade touches that folder. When settings do look gone after an update, it is almost always because the new install is reading a different, empty folder, not because anything was deleted; the old files are still where they always were. §18 has the recovery steps.

InstallHow to update
macOS appOpen the new DMG and drag NzbFast into Applications, replacing the old one. Your data folder is separate and is not touched.
Windows installerRun the new setup over the old install. Your data folder is separate and is not touched.
Docker (command line)docker pull nzbfast/nzbfast, remove the old container, then run the new one with exactly the same -v mappings. The image is disposable; the mapped /config folder is your install. If your run command uses a relative path like -v ./config:/config, run it from the same directory every time - from anywhere else, ./config is a different, empty folder.
Docker Composedocker compose pull && docker compose up -d, using the same compose file in the same place. The ./config in the file is anchored to the file's own folder, so keep the file where it is.
WatchtowerNothing to do: it recreates the container with the same mappings when a new image ships.
UnraidDocker tab → Check for UpdatesApply Update. Never remove and re-add the app to update it; if you ever do reinstall, keep the same appdata path so it finds your existing /config.
Synology (Container Manager)Download the new image, stop the container, and recreate it with the same volume settings - the walkthrough in the Synology guide covers it click by click, including doing it on a schedule.
Synology (package)Install the new .spk in Package Center; it upgrades in place.
Homebrewbrew upgrade nzbfast
Plain binaryReplace the binary. Your config stays wherever you made it (§17).
TipDocker users wiring up Sonarr or Radarr: put the API key in the container definition itself (-e NZBFAST_APIKEY=…, or the environment block of your compose file or Unraid template). A key stored there survives any container mishap, because it lives on the host, in the definition, and is re-applied on every start. A key you later set in Settings still wins over it.

15 · Command line

Everything the daemon does is also scriptable. The everyday commands:

CommandPurpose
nzbfast setupInteractive server setup.
nzbfast serveRun the daemon (dashboard + API + automation). --open opens the browser; --apikey sets the key by hand (§2); --bind chooses the listening address, default 0.0.0.0 (every interface), 127.0.0.1 for this machine only. See --help for the full flag list; every dashboard setting has a flag twin.
nzbfast get file.nzbDownload one NZB, full pipeline, no daemon. --preflight aborts early if the post can't complete; --password for encrypted sets.
nzbfast check file.nzbAvailability verdict (COMPLETE / REPAIRABLE / IMPOSSIBLE) without downloading payload.
nzbfast verify DIRVerify files against the PAR2 set in a directory.
nzbfast sysbenchThe system benchmark + diversity report, in the terminal.
nzbfast index / searchScan groups into the index / search it, without the daemon.
nzbfast import-sabImport servers from a SABnzbd ini.

Also available: inspect, probe, bench, bench-cpu, soak, fetch, spots/spot-search/spot-get (Spotnet), predb-seed (fills the pre database from before the feed was switched on), make-release-nzb/make-test-nzb (test fixtures), and post (uploads files as yEnc articles and writes the matching NZB; an operations tool, it requires an explicit --post-server and never picks a server for you). Every command takes --config and --help.

16 · API overview

Base endpoint: http://host:6789/api?mode=…&apikey=…&output=json. It is SABnzbd-compatible, so existing SAB integrations work unchanged. Two keys: the API key (full control) and the NZB key (add-only: addfile/addurl). addnzblnk is deliberately not in the add-only set: resolving one can spend metered indexer quota, which an add-only credential has no business doing.

AreaModes
Queuequeue (with name=delete/pause/resume/priority/switch), pause, resume, addfile, addurl, addnzblnk, retry, set_password
Infohistory, status/fullstatus, stats, version, server_stats, usage, log, warnings, plus /jobnzb/<nzo_id> (the job's own spooled .nzb back out, queue or history; full API key only)
Configget_config, config&name=<setting>&value=… (every Settings field), server_save/delete/test/enable/reorder, import_probe/apply
Index & wallindex_search, index_get, index_stats, index_scan_now, wall, wall_search/fix/refresh/art, plus newznab at /api?t=caps|search|tvsearch|movie and /getnzb/<id>
Automationwatchlist, watchlist_check_now, watch_calendar, feeds, smart_folders, schedule
Diagnosticssysbench, bench_history, connladder, pooltest, diversity, update_check, update_apply
NZBGet JSON-RPC/jsonrpc: status, listgroups, history, append, editqueue, rate, pause, log (Basic auth: any user, API key as password)
Preview / playback/stream/<nzo_id> (HTTP ranges; starting a parked library job needs ?t= token or key), /m3u/<id> (needs key; mints the token), /wall, /art/…

17 · Files & locations

Where the settings folder is depends on how nzbfast was installed. This one folder holds everything worth backing up:

InstallSettings folder
macOS app~/Library/Application Support/nzbfast/
Windows%LOCALAPPDATA%\nzbfast\
Docker / NAS containers/config inside the container, which is the host folder you mapped to it. On Unraid that is the app's appdata folder.
Synology package/var/packages/nzbfast/var/
TerminalThe folder you ran nzbfast setup in, or wherever --config / $NZBFAST_CONFIG points.

And what is inside it:

FileContents
config.local.jsonServer credentials and per-server options. Created by the wizard; editable in Settings. Passwords are obfuscated, not encrypted. Keep it private.
settings.jsonEvery setting changed in the dashboard. Lives next to the config; UI values override command-line flags. Delete a key (or the file) to fall back to flags/defaults.
apikeyThe API key nzbfast made for itself on a first run (§2). Lives next to the config; readable only by the account running nzbfast on macOS and Linux. Do not delete it to get a fresh key: on an install that has already run, nothing replaces it and the daemon comes back up with no key at all. Set a new one in Settings → Security instead.
index.dbThe release index (SQLite) + wall metadata. Safe to delete: it rebuilds from scanning (Settings → Indexing → Wipe does this for you).
<config>/.spool/Queue state (survives restarts), per-job NZBs, usage ledger, benchmark history, poster art cache.
Article journalInside each job's output folder while incomplete; powers crash resume and retry. Removed on success.
External toolsNone needed: RAR extraction and PAR2 repair are native. If an exotic set ever needs an external unrar or par2 as a fallback, nzbfast looks next to its executable, then on $PATH.

18 · Troubleshooting

SymptomCheck
Slow downloadsRun System benchmark; it names the bottleneck outright. If it's network: run Connection tuning, check per-server connection counts, and confirm your providers aren't all one backbone (Server diversity).
Slow only on very large jobs
(NAS or low-RAM machine)
Expected, and measurable: a starved memory budget spills caches to disk and costs 20–40% past ~87 GB. See Memory budget for the figures and how much RAM to give it. Smaller jobs are unaffected.
Download fails "articles missing"The post has expired or was taken down on your providers. A second provider on a different backbone rescues most of these. nzbfast check predicts this before downloading, and the wall's availability dot (§13) flags the likely-gone ones in advance. A first failure of this shape retries itself once after a cooldown, since propagation lag looks identical and clears on its own.
Finished archive wants a passwordHistory row shows 🔑: enter the password there; the job completes in place.
An archive fails to unpackPassword and repair failures name themselves in the History row. For anything else there is an escape hatch: Settings → Watch folder & post-processing → Unpack with external unrar (an advanced setting) hands unpacking to the unrar program installed on your machine instead of the built-in extractor. Leave it off otherwise: the built-in path is faster on every shape we have benchmarked, and hash-named obfuscated posts always use it regardless, since their renaming is something unrar cannot follow. The same switch for nzbfast get runs is the NZBFAST_NO_NATIVE_UNRAR=1 environment variable. If unrar unpacks an archive the built-in extractor refused, please report it so we can fix the built-in path.
Sonarr/Radarr can't connectPort 6789 reachable? API key correct (full key, not NZB key)? Client type set to SABnzbd?
The dashboard asks for an API key I never setA new install makes one for itself and prints it once at startup (§2). It is in the apikey file next to your config, and in the startup output. Or type a key of your own into Settings → Security from a browser that is already signed in.
All my settings look gone after an update
(servers, paths, API key)
Nothing in an update deletes settings; this means nzbfast is reading a different, empty folder. First: the API key field in Settings shows blank by design - click Show before concluding it is lost. On Docker, compare the /config mapping of the new container with the old one: a changed host path, a relative path run from a different directory, or a fresh appdata folder all start nzbfast from scratch while your real settings sit untouched at the previous path. Find the old folder (look for settings.json, your config file, and apikey - locations in §17), then either point the mapping back at it or copy those files into the new folder and restart. The startup log names the exact settings file in use: [settings] applying saved settings from …
Nothing on the network can reach the daemonCheck --bind: 127.0.0.1 serves only the machine nzbfast runs on. The default, 0.0.0.0, serves every interface. Then check the machine's own firewall for port 6789.
Browse card stays smallThe indexer grows in the background. Check Settings → Indexing groups are set, and give Deepen per scan time to accumulate history. "Scan now" forces a pass; the status line shows live progress.
Wall shows wrong/no artworkDetail sheet → ✎ Fix match or ↻ Refresh metadata. Movie lookups improve with a free OMDb key.
macOS says the application "nzbfast" can't be openedTwo causes, both quick. If you are using the plain -macos-universal.zip, double-click Start nzbfast.command, not the nzbfast file next to it: that one is the program itself, and Finder answers a double-click on it with exactly this message. The launcher is what sets it up and starts it. If the launcher gives the same message, the copy lost its Unix permission bit on the way to you: macOS keeps that bit inside the .zip, but chat apps, cloud drives and re-zips do not, so a build passed on by hand arrives unexecutable. Downloading the .dmg or the .zip straight from the releases page avoids it. To rescue the copy you already have, open Terminal, type chmod +x with a trailing space, drag Start nzbfast.command and the nzbfast file onto the window, and press Return, then double-click the launcher again.
Daemon won't start: port in useAnother instance is running, or change --port.
Where are the logs?The Log card on the dashboard, or the terminal/logfile you launched serve with.
Still stuck?The Log card usually names the culprit - include its tail when reporting an issue, along with your nzbfast --version.

This manual ships with every release. Settings, endpoints and defaults referenced here match the version it shipped with.