ESC

Type to search the knowledge base.

Design YouTube (Frontend)

Frontend system design for a video streaming product — player, feed, performance, caching, and offline concerns.

advanced4 min read
  • system-design
  • video
  • performance
  • caching

Scope the problem

Frontend system design interviews fail when candidates design the entire Google backend. Lock scope in the first five minutes.

In scope (frontend):

  • Home / subscription feed
  • Watch page: player, description, comments
  • Search results
  • Upload entry points (not the full encoder pipeline)

Out of scope unless asked: CDN POP placement, recommendation model training, ad auction internals.

Scale assumptions (state out loud):

  • Global users; mobile-heavy
  • Videos from seconds to multi-hour
  • Adaptive bitrate streaming (HLS/DASH)
  • Personalized home feed

High-level UI architecture

┌─────────────────────────────────────────────────────────┐
│ App shell (auth, nav, feature flags, i18n)              │
├──────────────┬──────────────────────────┬───────────────┤
│ Route modules│ Shared player runtime    │ Design system │
│ home/watch/  │ MediaSession, MSE/HLS    │ tokens, a11y  │
│ search/lib   │ quality, captions        │               │
└──────────────┴──────────────────────────┴───────────────┘

Prefer route-based code splitting. The watch page should not download the upload wizard.

Watch page — critical path

Goals

  1. First frame fast (LCP / time-to-first-frame)
  2. No layout jump when metadata loads
  3. Smooth quality switches
  4. Captions, keyboard, screen reader support

Data dependencies

Resource Priority Notes
Video manifest + first segment Highest Start playback ASAP
Title / channel / view count High SSR or streamed HTML
Related videos Medium Below fold; defer
Comments Low Paginate / virtualize

Rendering strategy

  • SSR/SSG shell for watch URL with title + poster + JSON-LD VideoObject
  • Client player mounts after hydration or via progressive enhancement
  • Stream secondary data (related, comments) after first paint
User navigates to /watch?v=id
  → HTML shell with poster + meta (SSR)
  → JS player bootstrap
  → fetch manifest
  → append init + media segments (MSE)
  → parallel: related + comments APIs

Player design

VideoPlayer
├── Media element (video)
├── Source controller (HLS.js / native HLS / DASH)
├── UI chrome (play, seek, volume, quality, captions, theater)
├── Keyboard manager
└── Analytics bridge (qos: startup, rebuffer, bitrate)

State machine (simplified): idle → loading → ready → playing ⇄ paused → ended with branches for error and rebuffering.

Expose imperative control via a small API so keyboard shortcuts and Media Session can share one controller.

Feed & virtualization

Home feed is a long list of cards. Use windowing (e.g. only mount ~20 visible cards). Preload thumbnails for the next viewport with loading="lazy" and priority for the LCP image.

Infinite scroll: cursor-based pagination; keep a single cache keyed by feed type + cursor. Abort in-flight requests on rapid filter changes.

Caching

Layer What Strategy
HTTP cache Static JS/CSS, thumbnails Long cache + hashed names
Service Worker App shell, recent watch metadata Network-first for APIs; cache-first for shell
Memory (React Query / SWR) GraphQL/REST responses Stale-while-revalidate; keyed by video id
IndexedDB Offline watch progress, drafts User-scoped

Do not cache personalized home feed aggressively without revalidation — users notice stale recommendations.

Performance budgets (example)

  • JS for watch route: < 200KB gzip initial
  • Time to first frame on mid-tier 4G: < 2.5s (target)
  • Interaction to seek response: < 100ms UI feedback

Techniques: split player vendor, prefetch manifest on hover of a card, content-visibility for offscreen sections, avoid layout thrash on progress bar updates (use transform).

Accessibility

  • Custom controls must be full keyboard operable
  • Captions default respect user preferences
  • Focus management when opening theater / mini-player
  • Reduced motion: limit autoplay animations

Tradeoffs to discuss

  1. SPA vs MPA for watch — MPA can win first paint; SPA wins sequential watch sessions
  2. Client vs server personalization of feed
  3. Third-party player vs in-house
  4. Comments: live websocket vs polling

Closing structure

End with: requirements recap → architecture diagram → critical path → scaling bottlenecks (comments fan-out, player QoS) → monitoring (RUM for rebuffers, CLS on feed).