The queue clears itself.
plungarr checks Sonarr, Radarr and SABnzbd every five minutes. It finishes the imports that only needed a nudge, clears the downloads that can never import, removes dead posts wedged at the head of the SABnzbd queue, and tells you about anything that genuinely needs a decision. It never touches a library file.
2026-09-07T14:57:28Z | sonarr | IMPORTED | Example.Show.S02E04.1080p.WEB-DL | 1 file(s) sent to ManualImport
2026-09-07T14:57:28Z | sonarr | REMOVED (discarded, no replacement search) | Example.Show.S01E35.1080p.WEB-DL | not an upgrade for the existing file
2026-09-07T14:57:28Z | sonarr | REMOVED+REPLACE | Example.Series.S05.720p.BluRay | archive not extracted
2026-09-07T14:57:29Z | radarr | IMPORTED | Example.Film.2009.1080p.BluRay | 3 file(s) sent to ManualImport
2026-09-07T14:57:29Z | sonarr | NOTIFY | Example.Kids.Show.S02E02.720p.WEB | flagged as a sample; left untouched (set SAMPLE_ACTION=replace or discard to auto-clear)
2026-09-07T14:57:31Z | sab | STALLED-REMOVED+REPLACE | Example.Movie.2019.2160p | head made 0 MB in 45 min
2026-09-07T14:57:31Z | sonarr | PROBLEM | Example Show S06E01 "Pilot" | 19 failed grab(s) in 48h, none imported since
2026-09-07T14:57:31Z | cycle | HEARTBEAT | queues processed in 3s | 3 gated, sweep idle
One cycle, lightly edited. Titles are made up; the behaviour is not.
What happens every cycle
Every stuck download has a reason. For the reasons plungarr recognises, it does what you would do by hand, and the policy for each is a setting.
| Situation | What plungarr does |
|---|---|
| Completed download blocked on a technicality: “matched to series/movie by ID”, “unable to determine if sample” | Verifies every file maps to the exact series or movie that was grabbed, then force-imports. A mapping mismatch is never imported. |
| Download that is not an upgrade for the existing file, reported on the queue row or only on the files inside it | NOT_UPGRADE_ACTION, default discard: remove and blocklist, keep the library file |
| Archive the download client never extracted | ARCHIVE_ACTION, default replace: remove, blocklist, search for a different release |
| Dangerous or executable file in the download | DANGEROUS_FILE_ACTION, default replace |
| File flagged as a sample | SAMPLE_ACTION, default notify, because short-form shows trip the sample detector on real episodes |
Sonarr: the episode number in the file name disagrees with the release folder name, usually a parser quirk like 1x8_720.mkv | FOLDER_MISMATCH_ACTION, default import: uses Sonarr's own file-to-episode mapping, only when it covers exactly the episodes that were grabbed and the mismatch looks like a parser quirk (another season, or many episodes). A few same-season episodes looks like a real mislabel and is reported. |
| Blocked on a technicality but nothing left to import: the folder is gone, or every file is already in the library | Gone: remove, blocklist, search for a replacement. Already in the library: NOT_UPGRADE_ACTION |
| Single-episode file that would replace a library file spanning more episodes | Treated as not an upgrade, so NOT_UPGRADE_ACTION applies |
| Sonarr: the episode title is still “TBA”, so Sonarr holds the import for up to 48 hours after airing | Left for Sonarr, which imports it once the title arrives. plungarr asks Sonarr for one metadata refresh of the series and reports the download only if it is still blocked an hour after the 48 hours, or if the episode has no air date. Never force-imported, because the file would be named “TBA”. |
| Completed or failed download that no configured arr grabbed: a series or movie deleted while it was downloading, or an NZB added by hand | ORPHAN_ACTION, default delete: removed from the queue and the download client, no blocklist, no search. Never while another configured instance owns it. |
| “No files found are eligible for import”, or a season pack that is one video file | Remove, blocklist, search for a replacement |
| Dead usenet post at the head of the SABnzbd queue: under 5 MB of progress in 45 minutes, or most articles missing | Remove through the arr that grabbed it, blocklist, search again. One per cycle, so live downloads keep going. |
| Job folder in the download client's completed directory that no arr queue item and no SAB job references any more, unchanged for a day (optional, needs the folder mounted) | LEFTOVER_ACTION, default notify: reported with size and age. delete removes it. SABnzbd never deletes completed job folders and an arr only cleans up its own. |
| Anything else | Logged, sent to your notifications if configured, and left alone. It never guesses. |
What it never does
- Never deletes a library file. The library review is report-only, always. Leftover download folders are deleted only when you opt in, only direct children of the folders you name, never through a symlink.
- Never imports a file that maps to a different series or movie than the one that was grabbed.
- Never acts on a state it does not recognise. Unknown means notify.
- Never races an import in progress: transitional items must be seen stuck across two cycles first.
DRY_RUN=truelogs every intended action and sends nothing.
Twice a day, it looks further
- Chronic failures. Every six hours it reads the arrs' history and flags any episode or movie with three or more failed grabs and no successful import since. That is your short list of things that need a human to pick a release.
- Suspect library files. Once a day it reports an MKV with no media info, a tiny file with no metadata, or a very low bitrate for its length. Each file is reported once. Nothing is deleted.
It tells you, on your schedule
Optional digests to Discord, Slack, ntfy, Gotify, Apprise or any JSON endpoint. Each category, from “needs attention” to “what plungarr did this month”, has its own cadence: immediate, daily, weekly, monthly or off. Items still waiting on you are re-sent after a week so nothing sits forgotten. Notifications.
Small on purpose
One Node file, no dependencies, MIT licence. It talks to Sonarr, Radarr and SABnzbd over their own HTTP APIs and needs nothing else. Any number of Sonarr and Radarr instances can be configured in one container. There is no web UI, by design: the policy is set once, and the log and digests are the interface. Why.