How I Built My Own Music Server for Three Years: Part Two. The Kalinka Architecture and Its Place Among Music Systems

Introduction

In July 2026, a detailed technical article on Habr caught my attention, describing a three-year journey to build a custom music server called Kalinka. The author, a developer and audiophile, shared the second part of their saga, focusing on the architecture and positioning of Kalinka among existing music systems. This article is not just a hobbyist project log — it’s a deep dive into software design for audio streaming, database management, and user experience. I’ll summarize the key insights, technical decisions, and lessons learned, linking to the original source for those who want the full story.

The project started as a personal need: the author wanted a music server that could handle a growing library of FLAC files, support multiple clients, and provide a web interface for easy management. After three years of iteration, Kalinka emerged as a self-hosted solution with a modular architecture. The article covers the challenges of metadata handling, search optimization, and integration with streaming protocols. For anyone considering building their own music server or evaluating open-source options like Navidrome or Jellyfin, this case study offers practical benchmarks and architectural patterns.

Source

The Kalinka Architecture: A Modular Approach

The developers behind Kalinka chose a microservices-inspired architecture, breaking the system into four main components: the library manager, the streaming engine, the metadata enricher, and the web frontend. Each component runs as a separate process, communicating via REST APIs and a message queue. This design allows independent scaling and updates — for example, the metadata enricher can be replaced without touching the streaming engine.

According to the article, the library manager uses SQLite for local databases and periodically syncs with a PostgreSQL instance for advanced queries. The streaming engine supports DLNA and AirPlay out of the box, with plans to add Spotify Connect compatibility. The frontend is built with React and uses WebSockets for real-time playback updates. The author emphasizes that this architecture reduced CPU usage by 40% compared to their earlier monolithic prototype.

Comparison with Existing Music Systems

The article provides a detailed comparison of Kalinka with popular self-hosted music servers. Below is a summary table based on the author’s benchmarks and feature analysis:

Feature Kalinka Navidrome Jellyfin (Music) Subsonic
Metadata scraping Built-in, MusicBrainz + Discogs Last.fm only MusicBrainz via plugin Plugin-dependent
Streaming protocols DLNA, AirPlay, HTTP Subsonic API, Web DLNA, Chromecast Subsonic API
Database SQLite + PostgreSQL SQLite SQLite SQLite
Search performance Full-text search, average 50ms Basic search, 200ms Basic search, 150ms Basic search, 300ms
Resource usage (idle) 80 MB RAM 120 MB RAM 200 MB RAM 150 MB RAM
Customizability High (open API) Medium (themes) High (plugins) Low

Note: These figures are from the original article and may vary depending on deployment. The author notes that Kalinka’s lower RAM usage comes from using a custom lightweight HTTP server instead of a full-stack framework like ASP.NET or Django.

Metadata Handling: The Hard Part

One of the biggest challenges the team faced was metadata consistency. Music libraries often have messy tags — missing album art, inconsistent artist names, or multiple editions of the same album. Kalinka addresses this with a three-stage pipeline:
1. Parsing — reads ID3 tags and extracts basic info.
2. Enrichment — queries MusicBrainz and Discogs APIs to fill gaps. The article mentions that the author wrote a custom rate limiter to avoid being blocked by these APIs.
3. Deduplication — uses fuzzy matching to merge duplicate entries (e.g., “The Beatles” vs. “Beatles, The”).

The result is a library that, according to the author, achieved 95% correct metadata for a collection of over 10,000 tracks. For comparison, Navidrome’s default scraping with Last.fm achieved about 80% accuracy in the same test.

Search and Discovery

Kalinka implements full-text search using SQLite’s FTS5 extension, indexing track titles, artists, albums, and even lyrics. The author reports search response times under 50 ms for libraries up to 50,000 tracks. For larger libraries, they recommend using PostgreSQL’s built-in full-text search, which scales better but requires more setup.

The article also describes a “smart shuffle” feature that uses collaborative filtering — similar to what Spotify uses — to suggest tracks based on listening history. However, the author admits this feature is still experimental and not ready for production use.

Streaming Performance

Streaming music requires low latency and consistent bitrate. Kalinka uses a custom streaming module that transcodes FLAC to MP3 on the fly for clients that don’t support lossless audio. The author tested with a Raspberry Pi 4 as the server and multiple Wi-Fi clients, achieving buffer-free playback for up to five simultaneous streams at 320 kbps. The article includes a graph showing CPU load never exceeded 60% under this load.

For local network streaming, DLNA works without transcoding, preserving original quality. The author notes that AirPlay support required reverse-engineering Apple’s protocol, which was the most time-consuming part of development.

Lessons Learned and Future Plans

The article concludes with a retrospective on what went wrong and what could be improved. Key lessons include:
- Start with a simple database schema. The first version used a normalized SQL schema with 15 tables, which made queries slow. Switching to a denormalized design with JSON fields for flexible metadata improved performance.
- Don’t over-engineer upfront. The author spent months building a plugin system that was never used. Instead, they recommend building a minimal viable product first.
- Open-source contributions matter. Kalinka uses several open-source libraries, and the author fixed bugs and contributed back to projects like MusicBrainz and SQLite FTS5.

Future plans include adding support for Spotify Connect, a mobile app (currently only web), and integration with Home Assistant for voice control. The author also hints at a possible open-source release, but no timeline is given.

Conclusion

The Kalinka project demonstrates that building a custom music server is feasible for a solo developer with patience and a clear architectural vision. While it doesn’t replace commercial solutions like Roon or Plex for most users, it offers unmatched customization for audiophiles who want full control over their music library. The article is a valuable resource for anyone considering a similar project, providing concrete benchmarks, design decisions, and honest reflections on challenges.

For those interested in self-hosted audio solutions, the original Habr article is worth reading in full. It’s a reminder that sometimes the best tools are the ones you build yourself — even if it takes three years.

Note: This article is based on external content. All technical details and claims are from the referenced source.

← All posts

Comments