The Arr Stack: Why It Feels Over-Engineered Until It Doesn't

The Arr Stack: Why It Feels Over-Engineered Until It Doesn't
Photo by Ning Shi / Unsplash

The appeal of running your own media server is straightforward enough. What catches people off guard is the stack that tends to form around it — Sonarr, Radarr, Lidarr, NZBGet, Jellyseerr, Tautulli. Six containers before you've watched a single episode. That count produces a predictable reaction: this is more infrastructure than the problem deserves.

That reaction is worth examining. Not because it's wrong — the stack is genuinely complex — but because it tends to change the first time something breaks.

One concern per container. That's not fragmentation.

The arr applications are built around a consistent design principle: each app owns exactly one concern. Sonarr knows about TV shows. Radarr knows about films. Lidarr knows about music. None of them know how to download anything — that's NZBGet or qBittorrent's responsibility. None of them know how to handle requests from other people in the household — that's Jellyseerr. None of them know whether the content is actually being watched — that's Tautulli.

This looks like fragmentation. It's actually isolation. Each boundary between apps is a defined handoff point where one concern ends and another begins. The alternative isn't simpler. It's a single application carrying all of these concerns simultaneously — where a bug in the download client affects media tracking, where a permissions problem in library management cascades through everything downstream, where the blast radius of any failure is the entire system.

The arr stack externalises those boundaries. That makes them visible, configurable, and — crucially — addressable when they break.

Where the architecture earns its complexity

The arr stack's failure modes cluster at the handoff points between applications. That's not a weakness in the design. It's where the architecture is doing the most work, and where misconfiguration has the highest surface area.

Path mapping is where most people hit friction first. Sonarr expects a completed download at /tv/Breaking Bad/Season 1/. NZBGet placed it in /downloads/complete/Breaking Bad/Season 1/. On the host, these may reference the same physical storage. Inside Docker, each container has its own view of the filesystem. If the volume mappings aren't consistent across every container that touches the same file, the handoff fails — and it fails silently. Sonarr reports the import complete. The file doesn't appear in Plex. No error message. Just absence.

PUID and PGID are the other load-bearing configuration. When Sonarr instructs NZBGet to move a completed download, that operation crosses a container boundary. If the user and group IDs don't match across those containers, the file stays where NZBGet put it. Sonarr can't touch a file it doesn't own. The move fails without fanfare.

Neither of these problems is unique to the arr stack. They're Docker problems, filesystem ownership problems, container isolation problems. What the arr stack does is make them explicit. You know where the handoffs are. You know which containers need matching configuration. That's not the same as making it easy — but it's considerably better than a system where the same problems exist invisibly, surfacing as random failures with no obvious cause.

The optional layers and when they earn their container

Jellyseerr and Tautulli are genuinely optional. The core stack — one or more arr apps plus a download client — functions without either. Whether they earn their place depends on what the setup is actually being used for.

Jellyseerr (or Overseerr for Plex users) adds a request management layer. Without it, requests come through wherever — text message, conversation, a note on the fridge — and get handled manually. With it, requests route through a UI that integrates directly with Sonarr and Radarr, and the person managing the stack can approve or auto-approve without touching the arr apps directly. For a single-user setup, Seerr is overhead without return. For a multi-user household where the person managing the stack wants to stop fielding ad-hoc requests, it earns its container quickly.

Tautulli is a different kind of addition. The arr stack automates acquisition. It doesn't generate any feedback about whether that automation is doing what it's supposed to do. Tautulli is observability for a system that would otherwise have no visibility into consumption — playback statistics, user history, what was watched once and abandoned, what was added a year ago and never opened.

For most people who've run this stack for any length of time, that information changes how they think about the automation. Acquisition is nearly frictionless. The library grows automatically. What Tautulli surfaces is the gap between what was downloaded and what was actually watched. That's a different kind of feedback than anything Sonarr or Radarr provides, and for some setups it's the most useful signal the entire stack generates.

The design principle underneath the container count

The arr stack is a specific implementation of a broader pattern: separating concerns across explicit boundaries produces systems that fail visibly rather than silently, and that can be debugged at the point of failure rather than requiring a complete rebuild to locate the problem.

The tradeoff is real and worth naming directly. More containers means more surface area to configure, more potential points of misconfiguration, more logs to correlate when something goes wrong. Six containers is a genuine operational commitment — especially for someone who wants a media server and not a homelab project. The complexity doesn't disappear because the design rationale is sound.

What the architecture provides in return is localisation. When Sonarr fails to import a file, the problem is bounded. It's a Sonarr configuration issue, or a permissions issue, or a path mapping issue — not a system-wide failure that takes everything down simultaneously. The debugging surface is smaller even when the container count is higher.

Whether that tradeoff is worth it depends on what the system needs to do and how much tolerance exists for occasional manual intervention. A single user running the stack for personal use, comfortable with occasional fixes, might find a simpler arrangement sufficient. A household where other people's expectations depend on the stack working reliably is a different calculation entirely.

Where the ecosystem is going

Some of the manual complexity in the arr stack has already been absorbed by the ecosystem itself. Prowlarr, which manages indexers centrally and syncs them to Sonarr and Radarr automatically, eliminates the per-app indexer configuration that was once a significant source of ongoing maintenance. That's the direction the project has been moving: reducing the manual surface area of the handoffs without collapsing the conceptual boundaries between concerns.

Whether the stack continues to consolidate further — or whether media server software starts absorbing some of these functions directly — isn't settled. The design philosophy has proven durable enough that the individual applications have grown considerably more capable without the overall architecture changing shape.

What remains genuinely open is whether the current complexity ceiling is the right one for every use case. The arr stack optimises for operational clarity at the cost of setup complexity. That tradeoff holds up well when someone is willing to invest in the initial configuration and understands what the stack is doing. In environments where it needs to work with minimal ongoing attention, the calculation is harder. There are simpler arrangements that cover most of the same ground. They also fail differently — less visibly, less predictably, at moments that are harder to trace.

The arr stack makes its complexity legible. Whether that's the right trade depends on what you need the system to do, and how much you want to understand what's happening inside it when something doesn't.

Ryan Mckernan
Author

Ryan Mckernan

IT service manager & infrastructure architect turning real-world IT messes into practical, documented fixes. I build systems, streamline ops, and share field notes at Painfully Useful—tested, refined, and repeatable.