Skip to main content

Design TikTok

Premium

You're asked to design a short-form video app like TikTok. Users see videos playing instantly when they open the app and can swipe to navigate between videos that are selected algorithmically.

This problem is similar to Design YouTube, but we'll focus on the recommendation feed aspects like ranking, prefetching, and feedback.

Clarify the requirements

  • How long are the videos? Fifteen to sixty seconds, which is why the whole file can be prefetched rather than streamed adaptively.
  • How fast must the next video start? Instantly on swipe. The next video must already be on the device, which determines the client design.
  • Is the recommendation system in scope? Assume yes and make it the center of the design rather than a side topic.
  • How fast does new content need to circulate? Minutes. A video uploaded now should be able to reach an audience today, which rules out purely batch-computed candidate sets.
  • Do we need follows and social features? Present, but secondary. The main feed is not follow-based, which is the product's defining difference from earlier social video.

Assume: sub-minute videos, instant playback on swipe, recommendation in scope, minute-level content circulation.

Back-of-envelope numbers

  • Users: 1B monthly1\text{B monthly}, 300M daily300\text{M daily}, each watching 100 videos/day100 \text{ videos/day}
  • Video views: 300M×100=30B views/day350k views/sec300\text{M} \times 100 = 30\text{B views/day} \approx 350\text{k views/sec}
  • Uploads: 50M videos/day600/sec50\text{M videos/day} \approx 600/\text{sec}
  • Video size after encoding: 3 MB\approx 3\text{ MB} for a 30-second clip, so storage grows 50M×3 MB=150 TB/day50\text{M} \times 3\text{ MB} = 150\text{ TB/day}
  • Egress: 30B views×3 MB=90 PB/day30\text{B views} \times 3\text{ MB} = 90\text{ PB/day}, essentially all of it from CDN edges
  • Engagement signals: several per view, so 1M events/sec\approx 1\text{M events/sec} feeding the ranking system

One million interaction events per second require a separate data pipeline. We can use that stream to update features during a session rather than waiting for an overnight batch.

High-level architecture

batch of video URLs

prefetch

watch signals

Client

① Feed service

② Candidate generation

③ Ranking model

④ Video index

⑤ CDN edge

⑥ Event stream

⑦ Feature store

Components
  1. Feed service. Returns a batch of ranked videos rather than one at a time.
  2. Candidate generation. Narrows billions of videos to a few hundred plausible ones, cheaply.
  3. Ranking model. Scores those candidates precisely for this user.
  4. Video index. Metadata, content signals, and engagement statistics per video.
  5. CDN edge. Serves the video files the client prefetches.
  6. Event stream. Watch time, completion, likes, shares, skips.
  7. Feature store. User and video features, updated continuously from the stream.
The feed service assembles a ranked batch of videos, the client prefetches several ahead so swipes are instant, and watch signals flow back into the ranking pipeline continuously.

Deep dive 1: prefetching, and why the feed returns a batch

The product promise is that a swipe plays the next video with no wait. There is no way to fetch a video after the swipe and meet that, so the video has to already be on the device.

The feed API returns a batch of five to ten videos with their URLs and metadata, rather than one at a time. The client plays the first and downloads the next few in the background, so a swipe plays from local storage.

That choice has three consequences:

  • How many to prefetch is a real tradeoff. Too few and a fast swiper outruns the buffer; too many and you waste the user's cellular data on videos they never reach. Adapting the depth to connection type and to observed swipe speed is the refinement that shows product thinking.
  • Prefetch progressively. Fetch the first seconds of the next video at high priority and the remainder at low, so the swipe is instant even if the full file hasn't arrived.
  • Batching costs freshness. A batch ranked thirty seconds ago can't reflect the last three videos watched. Keeping batches small, and letting the client request the next batch early, is how the design keeps in-session adaptation without giving up prefetch.

Because videos are short, the whole file can be fetched rather than streamed in segments, which removes the need for adaptive bitrate mid-video and simplifies delivery considerably compared to long-form. Pick the rendition once from the device and connection, and download it.

Deep dive 2: candidate generation and ranking

Scoring billions of videos for each of thirty billion daily requests is not possible, so the pipeline is staged: cheap and broad first, expensive and precise last.

Candidate generation cuts billions to a few hundred using several independent sources, each cheap:

  • Content similarity to what the user has engaged with, retrieved by embedding lookup.
  • Collaborative signals. Videos liked by users with similar histories.
  • Trending and fresh content in the user's language and region.
  • Follows and social graph, which is a minor source here rather than the primary one.

Running several sources in parallel and merging matters more than any one being good: each has a different blind spot, and their union is what stops the feed from collapsing into a single narrow topic.

Ranking scores those few hundred candidates with a model that would be too expensive to run over the full catalog. Optimize for predicted watch time, completion rate, and interaction probability rather than only clicks. We can use watch time as the primary signal because every view produces it, while likes are sparse and biased.

Diversity and freshness are applied after ranking, as a re-ordering step. A purely score-ordered feed becomes repetitive, showing five near-identical videos in a row, and repetition is what makes people close the app. Enforcing spacing between videos from one creator or one topic costs a little predicted engagement per video and improves session length, which is the metric that actually matters.

Deep dive 3: cold start, for users and for videos

Cold start is the problem this product is unusually exposed to, because there's no browsing behaviour to fall back on. It appears in two forms.

A new user has no history. The feed starts from broadly popular, high-quality content in their language and region, and the important design property is that early signals are weighted heavily, since the first few videos are effectively an interactive interview, and skipping three cooking videos should change the feed immediately. This is a strong argument for updating features from the event stream in near-real-time rather than in a nightly batch.

A new video has no engagement history, which matters more here than in most recommender systems, since fifty million uploads a day means a large share of the catalog is always cold. The standard approach is staged exposure:

  • Show the video to a small audience selected from its content signals: what's in the video, its audio, its captions, and the creator's history.
  • Measure completion rate and interaction on that small sample.
  • If it performs above the bar for its cohort, widen the audience; otherwise stop.
  • Repeat, so a genuinely engaging video escalates through progressively larger audiences within hours.

This is what makes it possible for a creator with no followers to reach millions, which is the product's central promise. It also needs a guard: the sample has to be large enough to be meaningful, or noise promotes videos randomly and demotes good ones.

Content signals are what make cold start work at all, since they're the only features a brand-new video has. Extracting embeddings from the video, its audio, and its text at upload time, as part of the encoding pipeline, is what gives ranking something to work with before any human has watched it.

Deep dive 4: the signal loop

A million events a second flow back from clients, and how quickly they reach the ranking system determines whether the feed feels responsive or stale.

Two paths, different latencies. Aggregate video statistics and user embeddings can update in near-real-time from the stream, so a skip affects the next batch. Full model retraining is a batch job on a much slower cycle. Confusing the two is a common mistake: you don't retrain a model in seconds, but you can absolutely update features in seconds, and that's what produces the in-session responsiveness users notice.

Define what each signal means. A quick skip is negative, while a partial watch on a long video may be positive. A rewatch is one of the strongest positive signals. The model depends on these definitions, not only on collecting events.

Reserve part of the feed for exploration. A model trained only on its previous choices will narrow over time because it never observes alternatives. We can use a small fraction of the feed for uncertain content, which keeps the system learning and gives new videos a path to an audience. This trades some short-term engagement for better discovery and learning.

Common pitfalls

  • Fetching the video after the swipe. There is no way to meet the latency requirement without prefetching.
  • Ranking the full catalog. Candidate generation has to narrow the set before any expensive scoring.
  • Optimizing for likes. Explicit signals are sparse and biased; watch time is available on every view.
  • A purely score-ordered feed. Repetition ends sessions, and diversity has to be enforced after ranking.
  • No exploration budget. The model narrows, and new creators never get a first audience.

Leveling signals

Mid-levelServes videos from a CDN, returns a personalized feed, and knows the client needs to prefetch so swipes are instant.
SeniorReturns batches sized for prefetch and adapts depth to connection, separates cheap candidate generation from expensive ranking, optimizes for watch time, and enforces diversity as a post-ranking step.
Staff+Handles video cold start with staged exposure driven by content embeddings extracted at upload, separates near-real-time feature updates from batch retraining, and reserves an exploration budget to counter the feedback loop's tendency to narrow.
Design YouTubeHard

Ingest and transcode continuous user uploads, then deliver them worldwide.

Design the Reddit HomepageMedium

Rank and serve a feed that stays current without recomputing everything.