What I've Learned Along the Way

A practical guide for running a great Navidrome library with clean tags, sane codecs, and smooth mobile playback (for Clipper and other Subsonic-compatible clients).

Written from the journey of building Clipper (iOS) and self-hosting Navidrome. The goal: help you avoid the usual potholes and get a rock-solid personal music setup.

Why this guide exists

With Navidrome, the app experience directly reflects the quality of your files and tags. If metadata is messy, your library looks messy. If formats and bitrates are odd, your mobile playback suffers.

This guide distills what actually matters:

  • sensible codecs & containers
  • realistic bitrate "transparency" targets
  • robust tagging that doesn't break by edition/compilation/multi-disc
  • transcoding strategies that don't burn CPU or battery
  • a few server and tooling tips that save time

Codecs & Containers

Container = the box (.m4a, .flac, .mp3)
Codec = how audio is encoded inside the box (AAC, ALAC, MP3, FLAC, Opus).
One container can hold different codecs — for example, .m4a can hold AAC or ALAC.

Lossless (archival / edit-safe)

  • FLAC (.flac) — open, efficient, and widely supported. Ideal for your master library.
  • ALAC (.m4a with ALAC codec) — Apple Lossless. Same quality as FLAC, slightly larger, plays natively across Apple devices.
  • WAV / AIFF — uncompressed, very large. Great for production, less ideal for tagging or archiving.

Lossy (portable / streaming-friendly)

  • AAC (.m4a with AAC codec) — modern, efficient, excellent on Apple devices.
  • MP3 (.mp3) — universal compatibility; larger for the same quality as AAC or Opus.
  • Opus (.opus) — extremely efficient, especially at low bitrates; stellar for streaming.

Takeaway: Keep a lossless master (FLAC or ALAC). Stream lossy (AAC, Opus, MP3) as needed.

Bitrate Targets & "Transparency"

"Transparency" means the point where most people can't tell the difference between a lossy file and its lossless source. Here are practical guidelines:

Codec Good Mobile Transparent for Most Notes
Opus 96–128 kbps 128–160 kbps Excellent efficiency and low latency
AAC (LC) 128–160 kbps 160–192 kbps Best choice for iOS; .m4a container
MP3 192–256 kbps 256–320 kbps Universal compatibility
FLAC / ALAC lossless lossless Use for archive or local hi-fi playback

Tips:

  • Use VBR (Variable Bitrate) whenever possible — it spends bits where they matter most.
  • If your masters are ALAC, transcoding to AAC is fast and native on Apple hardware.
  • For podcasts or speech, Opus 64–96 kbps is usually excellent.

Tagging That Never Bites Back

Navidrome organizes by tags, not folders. A well-tagged library is essential.

Core Tags

  • ALBUMARTIST – e.g. "Pink Floyd". Keeps albums together.
  • ALBUM, TITLE, ARTIST – fill consistently.
  • TRACKNUMBER, DISCNUMBER – proper ordering.
  • DATE / YEAR – use release year; add edition info to album title if needed.
  • COMPILATION – set to 1 or true for "Various Artists" albums.
  • Cover Art – embed JPEG 500–1000 px, and keep a cover.jpg fallback.

Nice-to-Have

  • MusicBrainz IDsMUSICBRAINZ_ALBUMID, MUSICBRAINZ_ARTISTID etc.
  • Genre – keep consistent casing and avoid long lists.
  • ReplayGain – store track and album gain/peak in tags for normalized playback.

Recommended Tag Editors

Suggested Folder Layout

/Music
  /Artist
    /YYYY - Album [Edition]
      01 - Track Title.flac
      cover.jpg

Navidrome uses tags (not filenames) for its database. More info: Navidrome Tagging Guidelines

Transcoding: On-the-Fly vs Pre-Encoded

On-the-fly: easiest, handled by Navidrome via ffmpeg
Pre-encoded: faster to stream, better for low-power servers

Example navidrome.toml

FFmpegPath = "/usr/bin/ffmpeg"

[Transcoding]
aac_160 = "ffmpeg -nostdin -v 0 -i {input} -map 0:a:0 -c:a aac -b:a 160k -f adts -"
mp3_192 = "ffmpeg -nostdin -v 0 -i {input} -map 0:a:0 -c:a libmp3lame -b:a 192k -f mp3 -"
opus_128 = "ffmpeg -nostdin -v 0 -i {input} -map 0:a:0 -c:a libopus -b:a 128k -vbr on -f opus -"

If transcoding fails on macOS with aac_at errors, switch to the built-in -c:a aac encoder or use a build with libfdk_aac.

Pre-Encoding Tips

  • Use beets convert or plain ffmpeg to create AAC/Opus mirrors for mobile.
  • Keep your FLAC/ALAC masters intact and tag them first.

Tools I Recommend

Tool Purpose Why It's Useful
Navidrome Music server Lightweight, fast, and tag-faithful
Beets Library manager Auto-tagging, ReplayGain, conversion
MusicBrainz Picard Tag editor Fetches verified metadata
FFmpeg Transcoding Swiss-army knife for audio/video
CopyParty File server Simple browser file upload
Docker / Compose Deployment Easy upgrades and reproducible stacks
rsync Backups/uploads Incremental, reliable syncs

Artist & Album Info (Last.fm Integration)

Clipper (and other clients) display rich Artist and Album info only if your Navidrome server connects to Last.fm.

Add your API credentials in navidrome.toml:

LastFM.Enabled = true
LastFM.ApiKey = "YOUR_LASTFM_API_KEY"
LastFM.Secret = "YOUR_LASTFM_API_SECRET"

You can get your API key and secret here:
https://www.last.fm/api/account/create

See official docs:
Navidrome – External Integrations
Navidrome Configuration Options

If artist info is missing in Clipper, double-check that your Navidrome instance has Last.fm enabled and valid keys, and that the server can reach the internet.

Server Tips That Help

  • Hardware: a Raspberry Pi 4 or any modest laptop is plenty for a few concurrent users.
  • Docker: mount your /music folder read-only and a small /data for DB/cache.
  • Rescans: schedule hourly or daily instead of watching constantly.
  • Permissions: use a dedicated user with consistent UID/GID across mounts.
  • Backups: rsync -a --delete /music /backup/music + snapshot /data.
  • Upload: rsync -av --progress --exclude='.DS_Store*' /Volumes/MUSIC/Converted/ user@musicserver:/media/music/.
  • Monitoring: Navidrome exposes Prometheus metrics for dashboards if desired.

Troubleshooting Quick Wins

Compilation split into many albums?

Ensure ALBUMARTIST="Various Artists" and COMPILATION=1 on each track.

Missing artwork?

Embed cover images and include cover.jpg in each album folder.

Weird sorting or duplicates?

Check for mismatched DATE, DISCNUMBER, or inconsistent casing.

Playback volumes vary?

Add ReplayGain tags with beet replaygain or ffmpeg -af volume=... tools.

Transcoding errors?

Verify the ffmpeg path and test the command manually on a file.

Suggested Setup (Practical Defaults)

  • Library master: FLAC or ALAC
  • Mobile stream/cache: AAC 160 kbps or Opus 128 kbps (VBR)
  • Tag workflow: Clean in Picard first, then import and manage with Beets
  • Navidrome: Docker, read-only music, hourly scan, Last.fm configured
  • Backups: nightly rsync, weekly off-site copy

References & Further Reading