# ADR 016: Recyclarr keeps quality profiles on the TRaSH Guides

- HTML version: https://robbiepalmer.me/projects/homelab/adrs/016-recyclarr-trash-guides
- Project: Home Lab (https://robbiepalmer.me/projects/homelab.md)
- Status: Accepted
- Date: 2026-08-23

# Context

Out of the box, Sonarr and Radarr ship crude quality profiles ("HD TV",
"Any"). They happily grab a low-effort WEBRip when a proper encode exists,
score every release the same, and let junk custom formats through. The
community-maintained [TRaSH Guides](https://trash-guides.info/) fix this with
curated quality profiles, custom formats (and their scores), quality size
limits, and naming, but they change weekly, and applying them by hand in two
web UIs means doing it twice and then never again.

The acquisition stack from [ADR 013](/projects/homelab/adrs/013-media-automation-arr-stack)
is only as good as its release-picking decisions. Bad profiles poison the
library early: wrong grabs get downloaded, imported, watched once, and kept.

# Decision

Run **Recyclarr** as a fifth container alongside the stack. It reads a small
YAML config and syncs TRaSH Guides state into both apps over their APIs on a
nightly schedule (`CRON_SCHEDULE`, default `@daily`):

* Sonarr gets the WEB-1080p quality profile plus its custom formats.
* Radarr gets the HD Bluray + WEB profile plus its custom formats.
* Both get guide-backed quality definitions (file size targets).

Operational shape:

* The official image publishes no `latest` tag, so the compose file pins the
  major version (`ghcr.io/recyclarr/recyclarr:8`).
* The container is rootless (`user:` instead of PUID/PGID), runs read-only
  with a tmpfs `/tmp`, and keeps all mutable state in `data/recyclarr/`.
* Provisioning generates `recyclarr.yml` once by fetching Recyclarr's
  pre-built TRaSH configs ([WEB-1080p][st] for Sonarr, [HD Bluray + WEB][rh]
  for Radarr) and substituting the container URLs and live API keys. Since
  Recyclarr v8 there are no include-by-name templates: each profile is
  *guide-backed* through its `trash_id`, so profile content keeps tracking
  the guides at every nightly sync without config changes.
* An existing `recyclarr.yml` is never overwritten, so manual score tweaks
  survive re-provisioning. Provisioning also fires one immediate sync so
  results are visible during bootstrap instead of waiting a day for cron.

First sync applied 37 custom formats plus quality sizes to Sonarr and 40
custom formats to Radarr, creating one curated profile in each app.

[st]: https://github.com/recyclarr/config-templates/blob/master/sonarr/templates/web-1080p.yml

[rh]: https://github.com/recyclarr/config-templates/blob/master/radarr/templates/hd-bluray-web.yml

# Alternatives

## Configure profiles by hand, once

* **Pros**: No extra container; full control in the native UIs.
* **Cons**: The guides update constantly (new formats, rescored releases);
  hand-applied settings drift within weeks and nobody re-does them.
* **Decision**: Rejected. Drift is the failure mode this exists to prevent.

## Leave factory defaults

* **Pros**: Zero effort.
* **Decision**: Rejected. Defaults rank releases poorly; that is the problem
  statement above.

## trash-updater (Python script)

* **Pros**: Older community tool doing a similar job.
* **Decision**: Rejected. Effectively unmaintained next to Recyclarr, which
  upstream TRaSH Guides document as the supported sync path.

# Consequences

### Pros

* Profile decisions track a curated, actively maintained source of truth.
* Both apps stay consistent because one config drives both.
* Sync is declarative YAML in the repo's data dir, reviewable and diffable.

### Cons

* A nightly job failing silently is possible: Recyclarr logs to
  `data/recyclarr/` and nothing alerts yet. The Netdata checklist should
  watch for it like the rest of the stack.
* New profiles apply to media added *after* they exist; existing library
  items need their profile switched manually (two items today, so cheap now
  and expensive later if skipped).

---

Markdown index of this site: https://robbiepalmer.me/llms.txt
