Courses › System Design › Question Breakdowns
Design Spotify
Fast playback from CDN and origin, licensing and signed URLs, versioned playlist sync and royalty-grade play counts.
Design a music streaming service like Spotify: users search a catalog of ~100M tracks, play music instantly on any device, build playlists, and listen offline. It's a question about serving audio at global scale with low start latency, a catalog and search, playlists that sync across devices, and counting plays accurately (artists are paid by them).
Requirements
Functional
- Users can search for tracks, albums, artists and playlists
- Users can play a track with playback starting almost instantly, and skip/seek
- Users can create and edit playlists, synced across their devices; playlists can be collaborative
- Premium users can download tracks for offline playback
- Every play is counted (for royalties and recommendations)
Out of scope: recommendation models (mention Discover Weekly as a consumer of play data), podcasts' video, social features, ads.
Non-functional
- Fast start: playback begins in < 300ms
- Scale: ~600M users, ~200M daily; ~100M tracks; peaks of ~10M concurrent streams
- Highly available playback; catalog changes can propagate in minutes
- Accurate play counts — royalty money depends on them
- Rights: tracks are only playable where licensed
[!TIP] Audio is small, but the catalog is long A 3-minute track at 160 kbps is only ~3.5 MB. The challenge isn't bandwidth per stream; it's that 100M tracks have an extremely long tail. A CDN caches the popular head; the tail must still start quickly from origin storage.
Capacity estimates
Core Entities
- Track — ID, title, artists, album, duration, audio files per quality/codec, territories licensed
- Album / Artist — metadata
- Playlist — owner, collaborators, ordered track entries (with added-by, added-at), version
- Play event — user, track, device, timestamp, ms played, offline flag
API
GET /v1/search?q=bohemian&types=track,artist&limit=20
GET /v1/tracks/{id}/playback → { "manifest": { "files": [{ "quality": "high", "url": "https://cdn.../a1.ogg?sig=..." }] } }
POST /v1/plays [{ "trackId": "t1", "msPlayed": 182000, "playedAt": "...", "offline": false }]
GET /v1/playlists/{id}?sinceVersion=41
PATCH /v1/playlists/{id} { "baseVersion": 41, "ops": [{ "op": "add", "trackId": "t9", "position": 3 }] }High-Level Design
app = client "Spotify Clients" @0,1
api = service "API Gateway" @1,1
meta = service "Catalog / Metadata" @2,0
search = store "Search Index" @3,0
pl = service "Playlist Service" @2,1
pldb = store "Playlists DB" @3,1
cdn = cache "CDN\n(audio files)" @1,2
origin = blob "Audio Storage\n(all encodings)" @2,2
plays = queue "Play Events\n(Kafka)" @3,2
app -> api
api -> meta
meta -> search
api -> pl
pl -> pldb
app -> cdn : audio
cdn -> origin : miss
app -> plays : play events- Metadata and search: catalog services serve track/album/artist data (heavily cached) and a search index.
- Playback: the app asks for a track's playback manifest (signed URLs per quality, with licensing checked), then fetches audio from the CDN, which falls back to origin storage.
- Playlists: a playlist service stores ordered entries with versions and syncs changes to devices.
- Plays: clients batch play events to an ingestion endpoint into Kafka for royalties, stats and recommendations.
Deep Dives
1. Starting playback fast
- Prefetch: when a track is nearly done (or likely next — the following playlist entry), the client fetches the start of the next track.
- Small first chunk: request the first few seconds first, at a modest bitrate, then continue at the chosen quality.
- CDN + origin: the popular head is in CDN edge caches; tail tracks come from origin over fast object storage. Spotify historically mixed CDN with peer-to-peer delivery on desktop to offload the tail; today a CDN is the standard answer.
- Encode each track in several codecs/bitrates (e.g. Ogg Vorbis/AAC at 96/160/320 kbps) to adapt to network and plan.
2. Rights and signed URLs
Licensing differs by country and changes over time. The playback endpoint checks the track's territories against the user's country and plan, then returns short-lived signed URLs; the CDN validates the signature, so audio can't be hot-linked or shared indefinitely. Audio is encrypted; keys are delivered with the manifest (DRM).
3. Playlists and sync
A playlist is an ordered list that can be edited from several devices — or several users for collaborative playlists.
- Store entries with a version number per playlist. Edits are expressed as operations (add at position, remove entry ID, move) with a base version.
- If the base version is current, apply and bump; otherwise rebase the ops on the newer version (entries are identified by IDs, not indexes, so most concurrent edits merge cleanly).
- Devices sync with
sinceVersionand get the ops or a fresh copy; push a "playlist changed" notification to trigger it. - Huge playlists (10k tracks) are paged.
4. Counting plays correctly
A play counts for royalties after 30 seconds. Clients send play events (batched, with retries); events may be duplicated or delayed (offline listening uploads hours later).
- Every event has a client-generated ID → dedup in the stream processor.
- Use event time, and accept late data (offline plays) into the right period.
- Raw events land in the data lake; a daily batch computes authoritative royalty counts, while streaming aggregates power "recently played" and real-time stats.
[!WARNING] Play counts are money Treat play events like financial records: durable ingestion (ack after Kafka write), idempotent processing, and a batch reconciliation that produces the numbers royalties are paid on. Fraud (bots looping a track) is filtered before payout.
5. Offline downloads
Downloaded tracks are stored encrypted on the device, with a license that must be renewed by going online at least every ~30 days. Plays offline are queued locally and uploaded later.
6. Search
Index tracks, artists, albums and playlists in Elasticsearch-style indexes with popularity as a ranking signal and typo tolerance; autocomplete uses a prefix structure (see Design Typeahead). Personalize ranking by the user's listening history.
What's expected at each level
- Mid-level: catalog + search, audio from object storage via a CDN, playlists in a database.
- Senior: fast start (prefetch, small first chunk), signed URLs and licensing, versioned playlist sync, deduplicated play events.
- Staff: long-tail delivery economics, collaborative playlist conflict handling, royalty-grade counting with late offline data, DRM and offline license renewal.