One hardware decision matters for Jellyfin: an Intel CPU with Quick Sync, 8th generation or newer. A $40 used desktop with an i3-8100 transcodes four 1080p streams at around 15W; an N100 mini PC does the same plus AV1 decode. Everything else — library naming, client choice, remote access — is configuration, and this guide walks the exact settings. The second most important sentence: transcoding is the fallback, not the plan. A well-set-up Jellyfin direct plays almost everything and touches the GPU only for the awkward cases.

Hardware: buy Quick Sync, skip the graphics card

Hardware1080p transcodes4K HDR → 1080p (tone-mapped)Notes
i3-8100 (UHD 630), ~$40 used~41–2The classic budget pick
N100 mini PC, ~$150~52–3AV1 decode, ~6W idle
i5-12500 (UHD 770)8+4+Overkill for most households
Raspberry Pi 50–1 (software)0Direct play only — avoid for transcoding

Figures are practical estimates, not lab numbers; subtitle burn-in and tone mapping eat capacity fastest. A discrete GPU is unnecessary unless you're serving many remote users — and then an Intel Arc A310 (~$100, AV1 encode) beats an old NVIDIA card that needs driver fiddling and more power.

The compose file, with GPU passthrough

# /opt/stacks/jellyfin/compose.yml
services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    ports:
      - "8096:8096"
    devices:
      - /dev/dri:/dev/dri
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /mnt/media:/media:ro
    restart: unless-stopped

The devices line hands the container Intel's render node. After first boot, go to Dashboard → Playback → Transcoding, set hardware acceleration to Intel QuickSync (QSV), tick the decode boxes for H.264/HEVC (and AV1 on 12th gen or newer), and enable tone mapping so 4K HDR doesn't turn into grey soup on SDR screens. The Jellyfin docs cover the per-GPU quirks if your hardware predates 8th gen. Verify it works by playing a 4K file at forced 1080p and watching intel_gpu_top on the host — CPU should stay nearly idle.

Name files the way the scanner thinks

Ninety percent of "Jellyfin misidentified my library" complaints are naming. The scanner wants year-disambiguated folders and season subfolders:

/mnt/media/
  Movies/
    Heat (1995)/
      Heat (1995).mkv
  Shows/
    Severance (2022)/
      Season 02/
        Severance (2022) S02E01.mkv

Do the renaming before the first scan — fixing identifications afterwards is one-at-a-time misery. If your library grows through the *arr stack, Sonarr and Radarr enforce this scheme automatically and the problem disappears. Keep Movies and Shows as separate Jellyfin libraries with separate roots; mixed folders confuse both the scanner and your family.

Clients: pick ones that direct play

Every transcode you avoid is server capacity you didn't need to buy. The rough hierarchy in 2026: Android TV / Nvidia Shield and the Jellyfin Media Player desktop app direct play nearly everything including HEVC and most subtitle formats. LG and Samsung native apps are serviceable but fussier about audio codecs (expect the occasional transcode for TrueHD). On Apple devices, Swiftfin or the third-party Infuse client (which speaks Jellyfin's API) direct play what the web client won't. The browser client is the worst case — no HEVC in most browsers means your 4K library transcodes. Two cheap wins: prefer SRT subtitles over PGS (image subtitles force burn-in, which forces a full video transcode), and set client bitrate limits to "Auto" rather than a low default that silently triggers transcoding on the LAN.

Remote access without exposing port 8096

Don't port-forward 8096 raw. Jellyfin's login page has had authentication CVEs historically, and it sees constant scanner traffic when exposed. Two sane options, detailed in remote access three ways: Tailscale for household devices (zero exposure, five-minute setup — install the app, sign in, done), or a reverse proxy with a real domain and TLS if you're serving family who won't install a VPN app. If you do proxy it publicly, enforce strong passwords for every account, and consider quality caps per user in Dashboard → Users so one relative on hotel Wi-Fi doesn't demand a 4K transcode at 3am.

Settings worth changing on day one

Scheduled tasks default to sensible times, but three are worth touching. Enable trickplay image generation (the scrubbing thumbnails) and schedule it overnight — it's CPU-heavy on first run across a big library, cheap forever after. Set chapter image extraction off on weak hardware; it's the classic "why is my server at 100% at 2am" culprit. And under Libraries, enable real-time monitoring so new files appear without waiting for the nightly scan. One omission that surprises people: Jellyfin ships no external "watched-state sync" or accounts service — your users and watch history live in ./config, so that directory belongs in your backups.

Create separate accounts per household member rather than sharing one: watch state, continue-watching rows, and recommendations are per-user, and the parental controls (max rating plus library access per account) only mean something when the kids aren't logged in as you. Accounts take a minute each in Dashboard → Users and save years of "who skipped ahead in our show" arguments.

What I'd do

Used 8th-gen Intel desktop or N100 mini PC, Debian and Docker, the compose file above with /dev/dri passed through, QSV plus tone mapping enabled and verified with intel_gpu_top. Rename the library to scanner conventions before the first scan. Android TV or Jellyfin Media Player on the couch, Swiftfin on the phones. Tailscale for travel, a Caddy-fronted domain only if non-technical family need in. Direct play as the default, transcoding as the safety net — in that order, a $150 box serves a whole household with single- digit CPU usage. More options for the rest of the stack live in the media server category.