DDSA Solutions
Case Study6 min read·

Design Spotify (Music Streaming)

How to design Spotify for interviews: music catalog, audio CDN delivery, playlists, search, recommendations sketch, and scaling play-count writes.

Spotify looks like Netflix until you zoom in. Audio files are smaller, sessions are longer and more interactive (skip, shuffle, offline), and the social layer (playlists, follows) matters as much as playback. Interviewers use it to test CDN delivery plus a write-heavy “now playing / play count” path without drowning in ML ranking detail.

Open with the framework: clarify free vs premium, offline downloads, and whether recommendations are in scope. Most rounds want catalog + stream + playlist; treat Discover Weekly as a stretch.

Functional requirements

  • Browse and search songs, albums, artists.
  • Stream audio with low startup latency; pause/seek/skip.
  • Create and edit playlists; follow artists/users.
  • Record plays for history and charts.
  • Optional: offline download, lyrics, podcasts (mention, do not build).

Non-functional

  • Time-to-first-byte under ~200 ms for popular tracks via CDN.
  • Availability over perfect consistency on play counts.
  • Handle flash crowds when a new album drops.
  • DRM / licensed delivery — acknowledge without designing Widevine.

Audio vs video

A 3-minute song at 160 kbps is about 3.6 MB (160×180/8 ≈ 3600 KB) — tiny next to a 4K movie. You still need CDN and adaptive bitrate (e.g. 96/160/320 kbps), but transcoding cost and storage math are kinder than Netflix.

Capacity sketch

Assume 100M songs, 500M users, 50M concurrent streams peak. Average song 5 MB × 3 bitrates ≈ 1.5 PB catalog before replication. Play events: if 10M concurrent users skip every 3 minutes, that is ~50K events/sec — perfect for Kafka, not for synchronous SQL updates per skip.

High-level architecture

  1. Catalog service — metadata (title, artist, album, duration) in PostgreSQL or Cassandra.
  2. Media pipeline — ingest masters, encode bitrates, store in object storage (file storage pattern).
  3. CDN — edge caches encrypted audio segments; clients fetch with signed URLs.
  4. Playlist service — user playlists as ordered track_id lists.
  5. Search — Elasticsearch on title/artist (search / typeahead).
  6. Playback / session service — authorize stream, return CDN URL + license.
  7. Event pipeline — play, skip, seek → Kafka → counters and recommendations offline.

Playback path

  1. Client requests play(track_id); API checks entitlement (premium / free with ads).
  2. Issue short-lived signed CDN URL for the chosen bitrate.
  3. Client streams via HTTPS; may switch bitrate mid-song if bandwidth drops.
  4. Emit play_started and play_completed events asynchronously.

Do not proxy audio through your app servers — same rule as Zoom media and Netflix egress. App tier is control plane; CDN is data plane.

Playlists and library

DataStoreNotes
Track metadataSQL / wide-columnStrong identity, joins to artists
Playlist itemsSQL or Redis listOrdered track_ids; shard by user_id
Liked songsSQL or KV setFast membership checks
Play countsCassandra / Redis + warehouseEventual; never block playback

Collaborative playlists need conflict handling — last-write-wins on item order is fine for MVP; OT/CRDT is overkill unless the interviewer pushes (point to Docs).

Search and browse

Index track/artist/album documents in Elasticsearch. Prefix search for artist names uses the same ideas as autocomplete. Hot homepage shelves (“Today’s Top Hits”) are precomputed lists cached in Redis and invalidated on chart jobs.

Recommendations (keep light)

Offline jobs train embeddings or collaborative filters nightly; online serving reads a precomputed candidate list per user from a feature store / KV. In a 45-minute interview, say “batch pipeline + cached candidates,” not “I will derive Word2Vec on the whiteboard.”

Scaling and failure

  • Shard users for playlists/library (sharding).
  • CDN origin shield to protect object storage on viral tracks.
  • Rate-limit anonymous scraping of the catalog (rate limiter).
  • If Kafka lags, playback still works — analytics delay is acceptable (CAP AP on counters).

Worked example

  1. User taps track T9 on a playlist.
  2. API validates premium, returns signed URL for 160 kbps object on CloudFront.
  3. Edge cache hit — audio starts in <100 ms.
  4. Client sends play_started; worker increments artist/track counters eventually.
  5. User skips at 0:40 — skip event feeds “skip rate” features for tomorrow’s model.

Offline and mobile

Downloads store encrypted blobs on device with a license that expires. Sync library deltas when online. Mention battery and storage quotas — interviewers like practical mobile constraints.

Ads and free tier

Free users may hear ads between tracks. Ad decisioning is a separate service returning audio creatives; the client stitches them into the play queue. Do not block playback on ad auction latency — fall back to a cached house ad. Premium skips this path entirely after entitlement check.

Artist payouts and royalty ledgers are payment-adjacent; point to the payment system article and keep them out of the critical stream path.

Interview narrative

Contrast with Netflix: smaller files, heavier social/playlist writes, play-event firehose. Draw CDN outside the API box, Kafka for plays, Elasticsearch for search. That story is complete without inventing a recommender PhD.

More in this series