SYSTEM DESIGN · DESIGN PROBLEMS · FEEDS AND SOCIAL · MEDIUM · 13 OF 41

Design TikTok: Short-Video Uploads, Transcoding and a For You Feed

How to design a short-video app with an interest-based feed: requirements, scale math for a billion daily viewers, upload and transcoding into adaptive bitrate renditions, CDN delivery and prefetching for instant playback, a recommendation pipeline of embedding retrieval and ranking, real-time watch signals, moderation before distribution, and the trade-offs to name.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
1 / 17

Press play to hear the narration, or step through at your own pace.

Notes

Listen

Requirements. Creators upload videos from fifteen seconds to a few minutes. Viewers get an endless, personalised For You feed and swipe to the next video. They can like, share and follow. Playback must feel instant. Live streaming, messaging, shopping and on-device editing effects are out of scope; editing happens on the phone before upload, so it doesn't touch our servers.

Qualities. After a swipe, the next video should start in roughly two hundred milliseconds, which is only possible if it's already downloading. The feed should adapt within the same session: skip three cooking videos and you should see fewer. Nothing harmful should reach a big audience before it's checked. Uploads are durable once accepted. Like counts and view counts can lag; that's fine.

Functional requirements
  • in scope:
  • • upload a video, 15 s to 3 min
  • • For You feed: endless,
  • personalised, swipe to next
  • • like, share, follow
  • • video starts instantly
  • out of scope:
  • • live streams, DMs, shop
  • • editing effects on device
Non-functional requirements
  • video start under ~200 ms
  • after a swipe
  • feed adapts within a session
  • (minutes, not days)
  • no harmful video goes wide
  • before review
  • upload durable once accepted
  • available over consistent:
  • counts can lag

Ask scale

Assume a billion daily users who each watch about a hundred short videos. That's a hundred billion video starts a day, around a million a second. The app fetches recommendations in batches of ten, so a hundred thousand feed calls a second. Uploads are much rarer: fifty million a day, about five hundred a second. And every view sends events like watch time, skip and like, so the event pipeline handles millions of messages a second.

Storage: a thirty-second original is about fifteen megabytes, and the transcoded renditions add about the same. Fifty million uploads a day is one and a half petabytes daily, hundreds of petabytes a year. Bandwidth is the real monster: a hundred billion views at a few megabytes each is three hundred petabytes a day, tens of terabits a second. That only works with a CDN serving popular videos from the edge, and with cheaper storage tiers for the long tail.

Traffic
DAU                  1B
videos watched/day   100 each
  100B starts/day   = ~1M/s
feed calls (10/batch)
  10B / 100,000 s   = 100K rps

uploads/day          50M
  50M / 100,000 s   = 500/s

events (watch, skip, like)
  ~3 per view       = ~3M/s
Storage and bandwidth
original 30 s          ~15 MB
renditions (5 sizes)   ~15 MB
50M x 30 MB          = 1.5 PB/day
  x 365              = ~550 PB/yr

per view ~3 MB watched
  (720p, about 15 s)
100B x 3 MB          = 300 PB/day
  = ~3.5 TB/s = ~28 Tbps

-> CDN, popular videos at edge

Define API

The API. Uploads are chunked and resumable, because creators are on mobile networks. Once all chunks land, the client creates the video with a caption and tags. The feed call returns ten items, each with a manifest URL that points at the CDN, a cover image and author info. The bytes never pass through our API. And the client batches engagement events, like how many milliseconds you watched and whether you liked or skipped, every few seconds.

Core API
POST /v1/uploads  -> { uploadId,
                    chunkUrls[] }
PUT  chunk N       (resumable)
POST /v1/videos
  { uploadId, caption, tags }
GET  /v1/feed?session=..&n=10
  -> [{ videoId, manifestUrl,
        coverUrl, author }]
POST /v1/events   (batched)
  [{ videoId, watchMs, action }]

Data model

Data model. The video record holds the owner, duration, tags, a list of renditions and a status that walks from uploaded, to transcoded, to reviewed, to live. View and like counts are sharded counters, because a viral video can get thousands of likes a second. Engagement events go to an append-only log. And every video and every user gets an embedding, a vector of numbers, which the recommender uses to find similar items quickly.

Records
video  (videoId PK, authorId,
        status, duration, tags,
        renditions[], createdAt)
  status: uploaded -> transcoded
          -> reviewed -> live
stats  videoId -> views, likes
       (sharded counters)
user   userId -> interests
events append-only log
embed  videoId -> vector[128]

High-level design

The upload path. Chunks go to the upload service and are assembled into the original in object storage. A transcoding job turns it into several resolutions and bitrates, cut into short segments. In parallel, moderation models scan sampled frames, audio and text. Only when transcoding and the first safety checks pass does the video's status flip to live and become eligible for the feed.

The watch path. The app asks the feed service for ten videos. It retrieves candidates near your taste from an embedding index, scores them with features, and returns the top ten. The app plays segments from the CDN and sends engagement events back. Those events update the feature store in near real time and train the models offline, which closes the loop: what you watch now shapes what you see next.

Deep dive: video

Deep dive one: the video pipeline. Split the original into short segments and encode them in parallel, so a one-minute video is ready in seconds rather than a minute. Produce a ladder of resolutions and bitrates, packaged as HLS or DASH: a small manifest plus many segment files. The player picks the right rung for the current network. A cost trick: once a video goes viral, spend more compute on a more efficient codec, because those bytes are sent billions of times.

Transcoding ladder
  • split into ~2 s segments
  • encode in parallel per segment
  • ladder: 360p, 540p, 720p,
  • 1080p; H.264 for reach,
  • HEVC or AV1 to save bytes
  • package as HLS or DASH:
  • manifest + segment files
  • popular: re-encode better
  • long tail: fewer renditions

Deep dive: playback

Deep dive two: instant playback. The trick is that the feed returns a batch, so the app prefetches the first segment or two of the next few videos while you watch the current one. When you swipe, playback starts from local memory. Start at a lower bitrate and step up. On the CDN side, popular videos are pushed to edges early, and a tiered cache shields object storage from misses. Track video start time and rebuffering per region and network.

Instant start
  • prefetch first 1-2 segments
  • of the next 2-3 videos
  • start low bitrate, step up
  • cover image while buffering
  • CDN: push new hot videos to
  • edges; tiered cache for
  • the long tail
  • measure: start time, rebuffer
  • ratio, by region and ISP

Deep dive: recommend

Deep dive three: recommendations. Retrieval gathers a couple of thousand candidates from several sources: nearest neighbours of your user embedding in an approximate index, trending videos in your region, creators you follow, and some brand-new videos that need test views. Filter out what you've seen or blocked. A ranking model predicts watch time, likes, shares and skips for a few hundred of them. A final pass adds diversity so you don't get ten of the same thing.

Why does it learn so fast? Because session signals flow through the stream into the feature store within seconds, so the very next feed call knows you skipped three cooking videos. Models retrain often. For cold start, a new user sees popular videos across varied topics, which works as a quick interest probe. A new video goes to a small test audience first, and if people watch it through, it gets shown to progressively larger groups.

Recommendation funnel
  • retrieve ~2,000 candidates:
  • embedding nearest neighbours
  • + trending in region
  • + followed creators
  • + fresh videos to test
  • filter: seen, blocked, unsafe
  • rank ~500 with a model that
  • predicts watch time, like,
  • share, skip
  • mix: diversity, top 10 out
Learning fast
  • events -> stream -> features
  • updated within seconds
  • (this session: skips, likes)
  • models retrain often; online
  • updates for fast signals
  • cold start, new user:
  • popular + quick interest probe
  • cold start, new video:
  • small test audience, expand
  • if watch-through is high

Trade-offs

Failures and monitoring. If transcoding backs up, uploads just take longer to go live, so autoscale on queue depth. If the feed service is slow, fall back to a cached regional trending list so people can still watch. If the event pipeline lags, recommendations get stale, but playback is unaffected. Watch video start time, rebuffering, watch-through rate, and how long risky videos wait for review.

Trade-offs to say out loud. Prefetching wastes some bytes when people swipe away, but buys instant starts. More renditions cost storage but give smoother playback. Staged distribution slows down how fast a video goes viral, but limits the damage of a harmful one. At ten times the scale, spend compute on better codecs for the hottest videos, add edge capacity, and run recommendation stacks per region.

Failures and monitoring
  • transcode backlog: uploads
  • wait; autoscale on queue
  • feed service slow: serve a
  • cached regional trending
  • list as fallback
  • event pipeline lag: recs go
  • stale, playback unaffected
  • viral spike: CDN absorbs it
  • watch: start time, rebuffer,
  • watch-through, review lag
Trade-offs to name
  • prefetch: wasted bytes if
  • you swipe away, for speed
  • more renditions: storage for
  • smoother playback
  • staged reach: slower virality
  • for safety
  • 10x: better codecs on hot
  • videos, more edge capacity,
  • regional recommenders

Say it like this

The summary. Resumable chunked uploads land in object storage, get transcoded in parallel into a bitrate ladder, and are checked by moderation before going wide. Delivery is a CDN plus client prefetching for instant starts. The feed retrieves candidates from embeddings, trending and fresh videos, ranks them by predicted engagement and diversifies. Engagement events stream back within seconds to keep the feed sharp.

The 60-second answer
  • upload: resumable chunks ->
  • object storage
  • transcode: parallel segments,
  • bitrate ladder, HLS/DASH
  • moderate before going wide
  • deliver: CDN + prefetch
  • feed: retrieve (embeddings,
  • trending, fresh) -> rank ->
  • diversify
  • events close the loop fast

Interview questions

How is a For You feed different from a follow-based feed?

It is built from predicted interest rather than the follow graph, so the main work is candidate retrieval and ranking at request time rather than fan-out at write time. Followed creators are just one candidate source among several.

How do you make the next video start instantly?

The feed returns a batch of videos, and the client prefetches the first one or two segments of the next few while the current one plays. Starting at a lower bitrate and serving from a nearby CDN edge removes most remaining delay.

What does the transcoding pipeline produce?

Several renditions at different resolutions and bitrates, split into short segments and described by an HLS or DASH manifest. The player switches between renditions as network conditions change.

How do you recommend videos to a brand-new user?

Start with popular and regionally trending videos across varied topics, then use the first few watch, skip and like signals in the session to update the user’s interest features. Within a few swipes, embedding retrieval has enough signal to personalise.

How does a new video get its first views?

It is shown to a small test audience that matches its topic, and if watch-through and engagement are strong, it is promoted to progressively larger audiences. This gives every video a chance while limiting the reach of weak or harmful content.

What is the biggest cost driver, and how do you reduce it?

Egress bandwidth for video delivery, which is orders of magnitude larger than uploads. Reduce it with CDN caching, efficient codecs such as HEVC or AV1 for popular videos, adaptive bitrate, and limiting prefetch to a couple of segments.

How do you count views and likes on a viral video?

Use sharded counters, splitting the hot key into many sub-counters that are summed on read, or aggregate events in a stream processor and write totals periodically. Counts may lag by seconds, which users accept.

Where does moderation fit in the pipeline?

Automated checks on frames, audio and text run during or right after transcoding, before the video becomes live. Borderline videos get limited reach until a human reviews them, and user reports can pull any video back.