Press play and music starts in under a second, anywhere in the world, on a phone that keeps switching between wifi and cellular. Once a week, a playlist appears that somehow knows you like a band you have never heard of. These are two very different systems wearing the same app, and both are worth understanding.
The core problem
Streaming has two enemies: startup latency and rebuffering. A user will forgive a slightly lower bitrate, but not silence. So the goal is to start fast and never stop, even when the network gets worse mid-song. Recommendation has a different enemy: the cold catalog. You have tens of millions of tracks and most of them almost never get played, so you cannot rank by popularity alone or you would recommend the same hits to everyone.
Key design decisions for playback
Serve audio from a CDN, not from origin. Tracks are static files. Encode each one into several bitrates ahead of time, push them to edge servers close to users, and let the client pick a bitrate based on measured throughput. The origin is only touched on a cache miss.
Chunk the audio and adapt. The client requests small segments rather than one long file. If bandwidth drops, the next segment is fetched at a lower bitrate. This is the same adaptive idea video streaming uses, applied to audio, where segments are small and switching is nearly inaudible.
Prefetch the next track. The player usually knows what comes next in a queue or playlist, so it fetches the first segments early. That is how the gap between songs feels like zero.
Cache aggressively on device. Recently played and downloaded tracks live in local storage, which cuts both latency and bandwidth cost, and makes offline playback possible.
Key design decisions for Discover Weekly
The recommendation side is a batch pipeline, not a live request. It runs on a schedule and writes a playlist per user that the app simply reads.
Collaborative filtering as the backbone. Build a large matrix of users and the tracks they play. Factor it into user vectors and track vectors so that similar listening habits sit near each other in a shared space. Two users who overlap heavily will surface each other's less common tracks. This is what makes the playlist feel personal without anyone hand-picking songs.
Blend in content and context. Pure collaborative filtering cannot rank a brand new track that nobody has played yet, the classic cold-start problem. So the pipeline adds signals from the audio itself and from text about the track, which lets fresh songs enter someone's recommendations before they have play history.
Filter what the user already knows. The point is discovery, so tracks the user plays often are removed, and the final list is capped at a fixed size and frozen for the week.
The trade-offs
Adaptive bitrate trades audio quality for continuity. On a bad connection you get a lower bitrate rather than a pause, which is almost always the right call for music. Prefetching trades bandwidth for smoothness, and wastes a little data when the user skips, which is a cheap price.
On recommendations, batch generation trades freshness for cost and stability. A weekly job over the full listening history is far cheaper than scoring in real time, and a playlist that does not change under your feet feels more trustworthy. The cost is that it cannot react to what you played an hour ago. Popularity-weighted ranking risks a feedback loop where hits get bigger, so the pipeline has to deliberately inject less popular tracks or discovery dies.
How the real system does it
The playback path leans on precomputed encodings, edge caching, and adaptive client-side bitrate selection, with device caching for the tracks you return to. The recommendation path is an offline pipeline built on matrix factorization over listening logs, mixed with content-based signals to handle new music, run on a weekly cadence and served as a static, per-user playlist.
The takeaway that generalizes: split the fast synchronous path from the heavy asynchronous one. Playback must answer in milliseconds, so keep it simple and cached. Personalization can take hours, so let it run as batch and just hand the app a finished answer.
I wrote the full breakdown, with diagrams and the data model, here: https://www.systemdesign.academy/interview/design-spotify
Top comments (0)