Spotify#
Problem statement (interviewer prompt)
Design Spotify: music + podcast catalogue, adaptive-bitrate playback, playlists (personal, collaborative, algorithmic - Discover Weekly), recommendation, offline mode, Spotify Connect (control playback on remote devices), and per-stream royalty accounting.
flowchart LR
U([User])
CAT[Catalog Service]
REC([Recommendations])
PLAY[Playback]
CDN
META[(Track metadata)]
AUD[(Audio files)]
U --> CAT --> META
U --> REC
U --> PLAY --> CDN
CDN --> AUD
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class U client;
class CAT,PLAY service;
class META,AUD datastore;
class REC compute;
flowchart TB
subgraph Clients
Desk
Mob
Web
Connect([Spotify Connect devices])
end
subgraph Edge
CDN[Music CDN<br/>Akamai / Fastly / GCP]
GW[Backend Gateway]
end
subgraph Catalog
CAT[Catalog Service]
TR[(Tracks metadata)]
ALB[(Albums)]
ART[(Artists)]
PL[(Playlists)]
end
subgraph Audio[Audio Pipeline]
LABEL([Label ingest])
DRM[DRM packaging]
ENC([Encoders<br/>Ogg Vorbis, AAC, FLAC])
BITRATE[96 / 160 / 320 kbps + lossless]
OBJ[(Object store)]
end
subgraph Discovery
HOME[Home]
SEARCH[Search]
DAILY[Daily Mix]
WEEKLY[Discover Weekly]
RADAR[Release Radar]
PODCAST[Podcasts]
end
subgraph Reco
CG([Candidate Gen])
RANK([Ranker])
GENRE([Genre embeddings])
TASTE[Taste profile]
NLP[Natural language playlist]
end
subgraph Playback
PSVC[Playback Service]
QUEUE[[Queue Manager]]
OFFLINE[Offline cache]
SHUFFLE[Smart shuffle]
GAPLESS[Gapless / crossfade]
end
subgraph Social
SHARE[Share / Friend feed]
COLL[Collaborative playlist]
BLEND[Blend]
end
subgraph Analytics
PLAY_LOG[Playback events]
KAFKA[[Kafka]]
BQ[(BigQuery / Snowflake)]
PAY[Royalty calculator]
end
subgraph Ads[Ads - free tier]
ADSVR[Ad server]
AUC[Auction]
end
Clients --> CDN
Clients --> GW --> Catalog
CDN --> OBJ
Audio --> OBJ
GW --> Discovery
Discovery --> Reco
Reco --> Taste[TASTE]
GW --> Playback --> CDN
Playback --> PLAY_LOG --> KAFKA --> BQ
Social --- Playback
Ads --- Playback
PAY --- BQ
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class Connect client;
class CDN,GW edge;
class CAT,DRM,BITRATE,HOME,SEARCH,DAILY,WEEKLY,RADAR,PODCAST,TASTE,NLP,PSVC,OFFLINE,SHUFFLE,GAPLESS,SHARE,COLL,BLEND,PLAY_LOG,PAY,ADSVR,AUC,Taste service;
class TR,ALB,ART,PL,BQ datastore;
class QUEUE,KAFKA queue;
class LABEL,ENC,CG,RANK,GENRE compute;
class OBJ storage;
Audio storage & delivery#
- Ogg Vorbis historically; AAC for Apple, FLAC for HiFi.
- Bitrates: 96, 160, 320 kbps (free / premium / very high).
- Files stored in object store, fronted by CDN.
- Tracks immutable once ingested; new master = new id.
Playback flow#
- Client requests
track_id→ control plane returns CDN URL + license. - Client downloads chunks ahead (10-30 s buffer).
- Telemetry every play emits a "stream" event for royalties + reco.
Recommendation#
- Collaborative filtering on listen graphs.
- Audio analysis features (tempo, key, valence) for cold start.
- NLP on playlist titles & genres.
- Discover Weekly: candidate set + personalized ranker.
Spotify Connect#
- Device discovery + control: phone controls playback on speaker / TV.
- Streams come from CDN to the playback device, not via phone.
Royalty calc#
- Per-stream play log → publisher splits via daily batch job.
- 30-second threshold for monetized streams.
Glossary & fundamentals#
Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.
| Tag | Concept | What it is | Page |
|---|---|---|---|
HLD |
CDN | edge caching for static assets | cdn |
HLD |
Pub/Sub & message brokers | topics, consumer groups, delivery semantics | pub-sub-pattern |
HLD |
Observability | metrics, logs, traces, SLOs | observability |
LLD |
Immutability | immutable types, persistent collections | immutability |
Quick reference#
Functional#
- Catalog of music + podcasts.
- Streaming playback (multi-device).
- Playlists (personal, collaborative, algorithmic).
- Recommendations (Discover Weekly, Daily Mix, Release Radar).
- Search, social sharing.
- Offline downloads.
- Spotify Connect (device handoff).
Non-functional#
- 600M+ MAU, 200M+ premium.
- p99 first audio < 500 ms.
- 99.99% playback availability.
Capacity#
- Tens of millions of tracks; each in 3-5 bitrates × few codecs.
- ~5 PB total catalog after multi-encode (much smaller than video CDN).
- 1B+ streams/day; royalty pipeline batch nightly.
Schema#
tracks(id, album_id, artists[], duration_ms, isrc, audio_files[])playlists(id, owner, collaborative, item_order[])streams(user_id, track_id, ts, source, duration_ms)Kafka topic for eventstaste_profile(user_id, vec)
Trade-offs#
- Many small files for albums; CDN cache hit rate critical.
- Hi-Fi (lossless) explodes bandwidth - gated by subscription.
- Per-stream royalty model demands precise accounting; need idempotent stream logging.
- Podcast model differs: exclusive shows, ads (DAI), serving with different SLAs.
Refs#
- Spotify Engineering blog (Apollo, Backstage, Discover Weekly explainers), "The Spotify Recommendation Stack" talks, ByteByteGo "Design Spotify", Alex Xu Vol 2.
FAQ#
How does Spotify stream music with low first audio latency?#
Clients fetch the CDN URL and DRM license from the control plane, then stream Ogg Vorbis or AAC chunks with a 10 to 30 second buffer. p99 first audio is typically under 500 ms.
How does Discover Weekly generate personalized playlists?#
Spotify combines collaborative filtering on listen graphs, audio analysis features like tempo and valence, and NLP on playlist titles. A candidate set is then ranked by a personalized model.
How does Spotify Connect stream to a remote speaker?#
The phone acts as a remote control. The target device (speaker, TV) pulls audio directly from the CDN using its own credentials, so the phone is not in the audio path.
How are per stream royalties calculated?#
Each play emits a stream event to Kafka and is logged to a warehouse. A nightly batch job aggregates streams per rights holder, applying a 30 second threshold for monetized plays.
What bitrates and codecs does Spotify use?#
Spotify historically used Ogg Vorbis at 96, 160, and 320 kbps for free, premium, and very high tiers. AAC is used on Apple platforms and FLAC powers the lossless HiFi tier.