Video upload and playback
Design a service where people upload videos and other people watch them. Uploads come from phones on unreliable networks. Playback should start quickly and adapt to the viewer's connection.
Where’s the slack?
Processing: minutes. Playback start: under 2 seconds. Upload: hours if needed.Uploading and processing have hours of slack. Starting playback has almost none. Designing both paths the same way is the usual way to fail this problem.
Uploads have hours of slack. Users do not expect a video to be watchable the instant the progress bar completes; video products show "processing" and users accept it. That makes the design tractable: transcoding into five resolutions is expensive, parallelisable, and off the user's critical path. You can retry it, queue it behind other work, and run it on cheap interruptible capacity.
Playback start has a hard budget of about two seconds. Beyond that, a growing share of viewers give up before the video starts, and video services track this number closely. The read path is built around that budget: content near the viewer, small first segments, a low starting bitrate that steps up.
Mid-playback has a different budget again. The player keeps a buffer, typically 10 to 30 seconds, which is slack it can spend fetching the next segments and adapting quality. Adaptive streaming depends on that buffer.
So there are two systems. One is optimised for throughput and cost, with hours to play with; the other is optimised for latency, with two seconds. They share only a storage bucket.
So: Hours of processing slack means transcoding is fully asynchronous, retryable, and can run on interruptible capacity. A two-second playback budget means segments must be static files on a CDN, which is why video is chopped into segments in the first place.
Work it through
Five stages, gated. You write your answer for each stage before its model answer unlocks. That is the core of the method.
Reference material for this problem. The diagrams below are here to check your own against once you have drawn it, not to read first.
The lifecycle
The numbers
Egress is ~180x ingest and it never stops. So the hard part is bandwidth, and the answer is that almost none of it may come from your origin. That is why video is segmented into static files in the first place.
The architecture
The mechanism
The decision this turns on
- —Bytes never touch your servers, so you never build a bandwidth tier.
- —Storage handles resumption, parallel chunks and retries natively.
- —Scales with upload volume without extra work from you.
- —Validation and scanning happen after the fact, not inline.
- —Full control: validate, scan and transform the stream as it arrives.
- —Simpler client, one endpoint, no presigning dance.
- —You now carry 8 GB/sec of ingest bandwidth and the servers to terminate it.
- —Every upload holds a connection for minutes, which wrecks your capacity model.
Follow-ups you should expect
Many interviews are decided in the follow-ups, not the first diagram.
Same shape, other products
The payload is far bigger than the metadata, and it should not go through your servers at all.
The moment you draw the file passing through your application server, you have made bandwidth your problem. Let the client talk to storage directly.
Others with this shape: Video upload and playback · Cloud file storage · Image hosting
How it is really built
Write your own answer first. Then read how teams who run this at scale describe it. Their constraints were real, and the write-ups often say what their choices cost.
- RFC 8216 — HTTP Live Streaming ↗The HLS spec. Playlists and segments are plain HTTP files, which is why a CDN can cache them like any other object.