Spotify is a music streaming system. It lets people browse a catalog of songs and podcasts, then press play to hear audio on their device.
The core promise is simple. When a listener taps the play button, the app should start sound quickly and keep it playing, even when the phone moves between strong and weak mobile networks.
Before scale, the simplest version is one client app talking to one backend. The backend answers catalog questions like artist, album, and track length, and it also provides the audio bytes for playback.
That baseline has one database for metadata and one object store for audio files. There is no CDN, no replicas, and no queue, so every play request depends on that single backend staying healthy and fast. Here is that baseline as a single end-to-end picture:
In the diagram, the mobile client sends requests over the internet to one app server. The app server reads track metadata from the metadata database and reads the audio file from the audio object store, then streams the audio back to the client over the same connection. With no extra layers, any slowdown in the app server, database, or object store shows up directly as a slower start or a stutter during playback.
For this course, the functional scope stays tight. A listener can browse, do simple search, and play audio, and the system should return the right track and then deliver the audio stream.
Two signals tell us when the single-server baseline stops working. The first is p95 start latency, meaning 95% of play attempts should begin within a target time, since a long tail of slow starts feels like the app is broken. The second is concurrent playback, meaning many users press play at the same time, which turns one busy moment into a sustained load on the backend and storage.
As soon as we scale the baseline, the same tradeoff words keep coming back. They tie a design choice to a visible result in Spotify, like a faster play start, a higher cloud bill, or fewer outages during traffic spikes.
This table anchors the vocabulary in the play flow and in background work: