SkillPilotAI

Case Study 5: YouTube / Hotstar Video Streaming

Video upload, transcoding and smooth adaptive streaming to tens of millions of people through a CDN, both VOD and live events like the IPL.

C.1 Requirements

Functional requirements:

  • A creator can upload videos (large files, resumable upload).
  • Videos are transcoded into multiple resolutions (240p to 4K) and codecs.
  • The viewer watches video with HLS/DASH adaptive bitrate: quality changes with the network.
  • Live streaming: an event like an IPL match is watched by crores of people at once, with low delay.
  • Search, video metadata (title, description, thumbnail) and view count.
  • Watch history and resume playback (from where you left off).
  • DRM and an entitlement check (subscription) for paid content.

Non-functional requirements:

  • Playback availability 99.99%; video start time < 2 seconds, rebuffering ratio < 1%.
  • Live glass-to-glass latency 10-30 seconds (standard HLS), ~3-5 seconds in low-latency mode.
  • Live peak: 2-3 crore+ concurrent viewers (Hotstar has publicly reported 2.5 crore+ concurrency during the IPL).
  • Durable uploads: not a single uploaded video may be lost (S3-like 11 nines).
  • Egress bandwidth at the Tbps level: 90%+ of traffic must be served by the CDN, not the origin.
  • Eventual consistency is OK for view counts and metadata.

C.2 Estimation (back-of-the-envelope)

ItemNumberHow it is derived
Daily active viewers (VOD)20 croreAssumption; every user watches avg 5 videos x 6 min = 30 min/day.
Uploads per day5 lakh videosAvg 10 min, raw ~500 MB = 250 TB raw/day.
Transcoded storage~1 PB/dayEach video has ~6 renditions + codecs; together with the 250 TB raw, the total is ~3-4x = ~1 PB/day, ~350 PB a year (moved to a cold tier).
VOD egress bandwidth~8 Tbps avg, ~20 Tbps peak20 crore x 1800 sec / 86400 = ~42 lakh avg concurrent viewers x 2 Mbps = ~8 Tbps; evening peak 2-3x.
Live IPL peak bandwidth~60-75 Tbps2.5 crore concurrent x avg 2.5-3 Mbps (mobile 480p-720p) = ~60-75 Tbps; possible only with multi-CDN.
Segment request rate (live)~40-60 lakh/sec2.5 crore viewers, 4-6 sec segment => 2.5 crore / 5 = 50 lakh segment GETs/sec + playlist refreshes.
Metadata DB~1 TB/year5 lakh videos/day x 5 KB = 2.5 GB/day; it is small, sharded MySQL/Postgres is enough.

C.3 API design

EndpointPurpose
POST /v1/uploadsStart an upload session; returns a resumable upload URL and upload_id
PUT /v1/uploads/{upload_id}/chunks/{n}Chunk upload (5-10 MB); if it fails only that chunk is retried
POST /v1/uploads/{upload_id}/completeFinalize after all chunks; triggers the transcoding job
GET /v1/videos/{id}/playbackAfter the entitlement check, a signed manifest URL (HLS m3u8 / DASH mpd) and a DRM license URL
GET /v1/live/{event_id}/playbackManifest URL of the live event, with CDN selection
POST /v1/videos/{id}/progressSave the watch position (for resume), batched heartbeat

C.4 Data model

Table / StoreFieldsWhy
videos (MySQL, sharded by video_id)video_id PK, owner_id, title, status (uploading/processing/ready), duration, manifest_path, created_atMetadata is relational and the status state machine needs ACID.
renditions (MySQL)video_id, resolution, codec, bitrate, segment_path_prefixTrack which quality is ready and generate the manifest.
object storage (S3/GCS)raw/{video_id}, hls/{video_id}/{res}/seg_0001.ts ya .m4s, manifestsCheap, durable blobs; this is the CDN's origin.
watch_history (Cassandra, partition key user_id)user_id, video_id, position_sec, updated_atVery many writes (heartbeats), simple key-based access.
view_counts (Redis + Kafka -> OLAP)video_id -> countA real-time approximate count in Redis, accurate analytics from stream processing.
entitlements (Redis cache + SQL)user_id, plan, valid_till, allowed_regionsA fast check is needed on every playback, and the DB must not take load at live peak.

C.5 High-level architecture

YouTube / Hotstar: architecture and request flow
  1. 1.Clients: Mobile / TV App and Web Player (ABR, HLS / DASH), Creator App (chunked upload), Broadcast Feed (stadium SRT / RTMP)
  2. 2.Edge: DNS / GSLB (region + CDN pick), Multi-CDN (Akamai, CloudFront, ISP caches) with origin shield
  3. 3.Load Balancer -> API Gateway (auth, rate limit)
  4. 4.Playback path: Playback Service (entitlement, signed URL) -> Redis entitlement check -> signed manifest + DRM URL (DRM Service: Widevine / FairPlay license)
  5. 5.Player fetches segments from the Multi-CDN edge; on a cache miss -> origin shield -> S3 Origin (raw/{id}, hls/{id}/{res}/seg_0001.m4s, manifests, 11 nines)
  6. 6.Upload path: Creator -> Upload Service (resumable, S3 multipart) -> Kafka / SQS transcode jobs + events -> Transcoding Workers (FFmpeg, parallel, spot) -> Packager (HLS + DASH CMAF + DRM) -> S3
  7. 7.Live path: stadium feed -> Live Ingest (redundant, 2 regions) -> Live Transcoder (real-time bitrates) -> Packager -> S3 origin
  8. 8.Data and events: MySQL (videos, renditions), Cassandra (watch_history), Redis (entitlement, view count); Kafka events to Thumbnail Worker + moderation, Search Indexer (status = ready), Analytics Pipeline (QoE, view counts)

VOD: 42 lakh avg concurrent x 2 Mbps = ~8 Tbps avg, ~20 Tbps peak, 90%+ from CDN. IPL: 2.5 cr concurrent x 2.5-3 Mbps = 60-75 Tbps, multi-CDN only, 95%+ cache hit.

  • Playback: the app picks the CDN + region via DNS/GSLB, LB -> API Gateway -> Playback Service; it checks entitlement in Redis and returns a signed manifest + DRM URL.
  • The player fetches segments straight from the Multi-CDN edge; on a miss, origin shield -> S3 Origin. 90%+ of traffic comes from the CDN, not the origin.
  • Upload: Creator -> Upload Service puts chunks in S3; on complete a Kafka job -> Transcoding Workers -> Packager -> S3.
  • Live: stadium feed -> Live Ingest (2 regions) -> Live Transcoder -> Packager -> S3 origin; Kafka events go to Thumbnail, Search, Analytics.
  • Bandwidth math: IPL 2.5 cr x 2.5-3 Mbps = 60-75 Tbps; hence multi-CDN and a 95%+ cache hit are essential.
ComponentWhat it does
Upload ServiceHandles resumable chunked upload; chunks go straight into an S3 multipart upload, and on complete an event goes into the job queue.
Transcoding WorkersSplit the video into 2-6 sec segments with FFmpeg and transcode in parallel (H.264/H.265/AV1, multiple bitrates); autoscaling on spot instances.
PackagerPackages renditions into HLS (m3u8) and DASH (mpd) manifests; with CMAF one segment serves both.
Playback ServiceDoes the entitlement check, returns the signed CDN URL and DRM license URL; picks the best CDN for the user's region/ISP.
Multi-CDNSegments are cached at the edge; embedded caches inside ISPs (YouTube publicly uses Google Global Cache) save last-mile traffic.
Live Ingest + Live PackagerThe RTMP/SRT feed comes from the stadium, is transcoded in real time, and a new segment and updated playlist are pushed to the origin every few seconds.
Analytics PipelinePlayer heartbeats (bitrate, buffering, errors) go into Kafka; stream processing produces QoE dashboards and view counts.

C.6 Main flows

Video upload and transcoding:

  1. The creator app gets an upload_id from POST /v1/uploads.
  2. The file goes in 10 MB chunks via S3 multipart upload; if the network breaks only missing chunks are retried.
  3. On the complete call the Upload Service sets video status = processing and puts a transcode job on Kafka.
  4. The splitter cuts the video into small chunks (at GOP boundaries) so it can be transcoded in parallel.
  5. Transcoding Workers encode every chunk in every resolution/bitrate, with output going to S3.
  6. The Packager joins the segments into HLS/DASH manifests and applies DRM encryption.
  7. Thumbnail and content moderation workers run in parallel.
  8. When everything is ready, status = ready, the Search Indexer is updated and subscribers are notified.

VOD playback (adaptive bitrate):

  1. The user presses play and the app calls GET /v1/videos/{id}/playback.
  2. Playback Service checks entitlement in Redis and returns a signed master manifest URL.
  3. The player fetches the master manifest from the CDN; it lists all quality levels.
  4. The player estimates bandwidth, picks a rendition and fetches segments from the CDN edge.
  5. On an edge cache miss it fetches from the mid-tier/origin shield, then from the S3 origin.
  6. If the network slows, the player picks the next segment at a lower bitrate (ABR); no rebuffering.
  7. The player sends progress and a QoE heartbeat every 30 sec.

Live IPL streaming:

  1. The stadium production feed arrives over SRT/RTMP at redundant ingest servers (two regions).
  2. The live transcoder produces multiple bitrates in real time, in 4-6 sec segments.
  3. The Live Packager writes the new segment to the origin and updates the media playlist.
  4. Multiple CDNs sit behind an origin shield; the CDN TTL of every playlist is very short (1-2 sec), segments get a long one.
  5. Crores of players refresh the playlist every few seconds and fetch new segments from the edge.
  6. Request coalescing: when thousands of identical requests miss at one edge, only one request goes to the origin.
  7. Under overload, graceful degradation: lower the default bitrate, switch off non-critical features (comments, recommendations).

C.7 Deep dives

Upload -> split -> parallel transcode -> package (VOD)
  1. 1.Creator App: POST /uploads -> upload_id; Upload Service: 10 MB chunks, only the missing chunk is retried; S3 raw/ multipart
  2. 2.Complete -> Kafka job, status = processing -> Splitter: small chunks at GOP boundaries
  3. 3.Transcoding Workers (FFmpeg): every chunk x every rendition in parallel (240p, 480p, 720p, 1080p, 4K)
  4. 4.Publish low-res first, HD later; popular creators = priority queue
  5. 5.Packager: HLS m3u8 + DASH mpd, CMAF, DRM encrypt -> S3 hls/{id}/{res}/ segments + manifests
  6. 6.status = ready -> Search Indexer + notify subscribers; thumbnail + moderation workers in parallel
VOD playback: adaptive bitrate ABR
  1. 1.Player: GET /playback -> master.m3u8 signed URL (240p, 480p, 720p, 1080p, 4K)
  2. 2.The player picks the quality for every segment (4-6 s) based on bandwidth: 1080p 1080p 1080p ...
  3. 3.Network slow: 720p, 480p, 480p; seg 1 ... seg 8: no rebuffering, only the quality drops
  4. 4.CDN edge (hit 90%+) -> Mid-tier / shield (miss) -> S3 origin
  5. 5.Progress + QoE heartbeat every 30 s -> Kafka -> analytics
Live IPL: thundering herd + coalescing
  1. 1.2.5 cr players: playlist refresh every 4-6 s = ~50 lakh segment GET/s
  2. 2.Edge PoP 1, 2, 3: 1000 misses on each
  3. 3.Origin shield: request coalescing, 1 request
  4. 4.Live Packager origin: playlist TTL 1-2 s, long segment TTL
  5. 5.Toss/wicket spike: pre-warm, jitter + backoff, rate limit, comments/reco OFF

Problem: crores of concurrent viewers at live peak and origin overload. Multi-CDN + origin shield + request coalescing; 95%+ cache hit. Pre-warm capacity and load test before the match, because autoscaling takes minutes while traffic rises in seconds at the toss.

Problem: thundering herd: everyone logs in/refreshes at once at match start or a wicket. Cache and pre-compute login, entitlement and config; client-side jitter and exponential backoff; API Gateway rate limiting; switch off non-critical APIs with a feature flag (graceful degradation).

Problem: transcoding a large video is slow (a 1-hour 4K video). Split the video into chunks and transcode in parallel on thousands of workers (map-reduce style). Use a priority queue for popular creators; publish the low resolution first, HD later.

Problem: buffering on a poor network (2G/3G, crowded towers). ABR (HLS/DASH) switches quality on every segment; use small segments; efficient codecs (H.265/AV1) give the same quality at a lower bitrate; the player adapts to its buffer health.

Problem: storage cost growing to exabytes. Keep popular videos on a hot tier and old/rarely watched ones on cold storage (S3 Glacier-like); for the long tail keep only a few renditions and transcode the rest on demand.

Problem: piracy and unauthorised access. DRM (Widevine, FairPlay, PlayReady) segment encryption, signed CDN URLs with a short expiry, a concurrent stream limit per account, forensic watermarking.

C.8 Trade-offs

DecisionWhat was chosen and why
HLS vs DASHSupport both: HLS is needed for Apple devices, DASH on Android/web; with CMAF one segment format is reused by both, halving storage.
Live latency vs stabilityStandard HLS (6 sec segments) is more stable and cacheable but 20-30 sec behind; LL-HLS has lower latency but more requests on the CDN.
Single CDN vs Multi-CDNMulti-CDN: at IPL scale one CDN has capacity limits and outage risk; cost and complexity are higher but it is essential for availability.
Pre-transcode all vs on-demandPopular content gets all renditions up front; the long tail is on-demand: a storage vs compute trade-off.
Push vs pull to CDNPull (lazy cache) for VOD, pull through an origin shield + pre-warm for live; push only for known hot content.

C.9 Interview tips

  • Design the upload path and the playback path separately: their scale and nature differ.
  • Explain adaptive bitrate and segments clearly (manifest + chunks).
  • Show the bandwidth math: concurrent x bitrate = Tbps; it proves the importance of the CDN by itself.
  • For live, always mention the thundering herd, pre-warming and graceful degradation.
  • Explain transcoding as a queue + parallel workers + idempotent jobs.