System Design · Live Video

Design Hotstar Live Streaming for IPL (25M+ Concurrent Viewers)

What it takes to stream one cricket match to tens of millions of phones at once: the ingest and transcoding pipeline, low-latency HLS, CDNs that must be reserved before the toss, scaling ahead of a Dhoni walk-in, ads at every over break, and a plan for when things break.

✍️ Pranjal Jain, Ex-Microsoft · IIT Kanpur 📅 10 October 2026 ⏱ 17 min read
A floodlit cricket stadium beaming a broadcast that splits into millions of streams across a map of India
TL;DR
  • Live IPL is one stream watched by everyone at the same second. Video bytes are a CDN problem; the hardest backend problems are synchronised surges driven by match events and ad breaks.
  • Pipeline: stadium production → redundant contribution feeds → cloud live transcoder (ABR ladder, many commentary languages) → packager (HLS/DASH, CMAF) → origin → shield → multi-CDN → player.
  • Low-latency HLS / chunked CMAF cuts glass-to-glass delay from ~30 s to a few seconds, at the cost of request volume and tighter buffers.
  • Pre-scale backends and reserve CDN capacity from a forecast; reactive autoscaling is too slow for a jump of millions in a minute.
  • SSAI with per-cohort manifests and pre-computed ad decisions survives every over break; a degradation ladder keeps playback alive when everything else is on fire.

Hotstar (now JioHotstar) has publicly reported concurrency records for cricket that were world records for live streaming at the time: around 25 million concurrent viewers during the 2019 World Cup semi-final, and far higher figures reported in later tournaments. Its engineers have also spoken publicly about the techniques behind it: pre-scaling, load testing at enormous scale, and deliberately switching off features under load. "Design Hotstar for IPL" has therefore become a favourite question at Indian product companies.

The question looks like "design YouTube, but live". It is actually a different problem: everyone watches the same thing at the same time, so caching is easy but load is perfectly synchronised. This post is built around that difference. For on-demand video fundamentals (ABR, transcoding ladders, CDN basics), see design YouTube/Netflix.

Why Live Cricket Is Uniquely Hard

  • Event-driven surges: concurrency jumps when a star batter walks in, in the last overs of a close chase, or after a rain delay ends. People who left the app all return within a minute, triggering a login and home-screen surge on top of playback.
  • Everyone hits the same ad break: at the end of each over, every viewer needs an ad decision and ad segments at once.
  • Latency vs spoilers: if your stream is 40 seconds behind TV, WhatsApp groups and neighbours' cheers spoil the six before your users see it.
  • Device and network diversity: low-end Android phones on congested 4G in small towns, smart TVs on fibre, all on one stream.
  • No retakes: an on-demand outage delays a show; a live outage loses the moment forever, and it trends on social media in seconds.

Requirements

Functional

  • Stream live matches in multiple qualities and multiple commentary languages (English, Hindi, Tamil, Telugu, Kannada, Bengali and more).
  • Pause and rewind within a live window (DVR), "go live" button, multiple camera angles optionally.
  • Live scorecard, key moments, social features (reactions, polls).
  • Ads at over breaks and strategic timeouts; subscription tiers.
  • Highlights and replays shortly after key moments.

Non-functional

  • Scale: 25M+ concurrent viewers with headroom.
  • Playback quality: startup within a few seconds, rebuffering ratio well under 1%.
  • Glass-to-glass latency: target under ~10 s, ideally close to TV broadcast delay.
  • Availability: playback must survive failures of any single component, region or CDN.
  • Cost control: bandwidth is enormous; bitrate choices matter.

Capacity Estimates

Interview assumptions, not platform figures:

  • 25M concurrent viewers at peak; ramp from 10M to 25M in about 15 minutes during a tense finish, with bursts of ~1M new viewers per minute.
  • Average delivered bitrate ~1.2 Mbps (mostly mobile at 480p to 720p, some TVs at 1080p+). Egress = 25M × 1.2 Mbps = 30 Tbps. No single CDN or data center serves that comfortably; multiple CDNs and ISP-embedded caches are mandatory.
  • Segment requests: with 4-second segments, each viewer fetches one video segment (plus audio, if separate) every 4 s → 25M / 4 ≈ 6M+ segment requests/s.
  • Manifest requests: live playlists are refreshed roughly once per segment duration → another ~6M requests/s. With LL-HLS partial segments of ~1 s, request rates multiply.
  • Backend APIs: heartbeats, entitlement checks, scorecard, ads, analytics. Even at one API call per viewer per 20 s, that is 1.25M requests/s, all of which would melt an origin if not cached or batched.
  • Ad breaks: ~25M ad decisions needed within a few seconds every over (roughly every 4 minutes).
25M+
Concurrent viewers
~30 Tbps
Peak egress
~12M/s
Segment + manifest requests
~25M
Ad decisions per break

The Ingest-to-Player Pipeline

STADIUM CLOUD (two regions, active-active) cameras ─► production ─► contribution encoders ─┬─► ingest A ─┐ (director cut, graphics, (primary + backup │ │ commentary mixes) links: fibre / SRT / └─► ingest B ─┤ satellite) ▼ ┌──────────────────────────────────┐ │ Live transcoder (per language) │ │ ABR ladder: 240p ... 1080p │ │ GOP-aligned, 1-4 s segments │ └──────────────┬───────────────────┘ ▼ ┌──────────────────────────────────┐ │ Packager: HLS + DASH (CMAF), │ │ DRM, SCTE-35 ad markers, DVR win │ └──────────────┬───────────────────┘ ▼ Origin (redundant) ─► Origin shield │ ┌───────────────┬───────────────┼───────────────┐ ▼ ▼ ▼ ▼ CDN 1 CDN 2 ISP-embedded CDN 3 │ │ caches │ └───────────────┴───── players (phones, TVs) ───┘ ▲ Control plane: CDN steering, entitlement, ads (SSAI), feature flags, QoE telemetry

Stage by stage

  1. Production: the broadcaster's production team creates the director's cut with graphics. Commentary for each language is mixed separately; each language becomes a separate audio rendition or a separate feed.
  2. Contribution: high-bitrate mezzanine streams leave the stadium over redundant paths (dedicated fibre, internet with SRT for loss recovery, satellite as backup) to two independent cloud ingest points. Losing one path must not drop the stream.
  3. Live transcoding: each feed is encoded in real time into an ABR ladder. Unlike on-demand, there is no second pass: encoders must keep up with real time, so they run on dedicated capacity (often hardware-accelerated) with 1+1 redundancy. Keyframes are aligned across renditions so players switch quality cleanly.
  4. Packaging: produce HLS and DASH manifests referencing CMAF segments (one set of media files for both protocols), apply DRM, insert SCTE-35 cue markers at ad break boundaries, and maintain a DVR window (say the last 2 hours) for rewind.
  5. Origin and shield: origins store the rolling window of segments; an origin shield layer absorbs CDN misses so origins see only a handful of requests per segment.
  6. Distribution: multiple CDNs plus caches inside ISPs (critical in India, where a few large mobile operators carry most viewers) serve the bytes.
  7. Playback: the player picks a CDN (via steering), fetches manifests and segments, adapts bitrate, inserts or plays ads, and reports quality-of-experience telemetry.

Redundancy everywhere

Every stage runs at least 1+1: two contribution paths, two ingest regions, two encoder chains per language, two packagers writing to replicated origins. Packagers use synchronised timestamps so that the two chains produce interchangeable segments; a player or CDN can fail over between them without a glitch.

Low-Latency HLS: Getting Close to TV

Where the delay comes from

ComponentClassic HLS (6 s segments)Low-latency (CMAF chunks / LL-HLS)
Capture, production, contribution1 to 3 s1 to 3 s
Encoding1 to 2 s~1 s
Segment duration (must finish before publishing)6 sPartial segments of ~0.3 to 1 s published while encoding
CDN propagation~1 s~0.5 s
Player buffer (typically ~3 segments)~18 s~1 to 3 s
Total glass-to-glass~25 to 30 s~4 to 8 s

How low latency is achieved

  • Chunked CMAF: a segment is split into small chunks that are sent over HTTP chunked transfer encoding as soon as each is encoded, so the player can start playing a segment before it is complete.
  • LL-HLS (Apple's extension): manifests advertise partial segments, support blocking playlist reload (the server holds the manifest request until the next part exists, avoiding wasteful polling) and preload hints so the player requests the next part before it is published.
  • Smaller buffers: lower latency means less buffer to absorb network jitter, so rebuffering risk rises. Players adjust playback speed slightly (e.g. 0.95x to 1.05x) to keep a target latency without stalling.

The trade-off to state in the interview

Low latency multiplies request rates (more, smaller objects), stresses CDNs that must support chunked delivery and blocking requests, and increases rebuffering on poor networks. A sensible design offers low-latency mode on good connections and falls back to a larger buffer for viewers on weak networks, where a smooth stream matters more than 10 seconds of delay. Also keep latency consistent across viewers; a friend's phone 15 seconds ahead is as bad as being behind TV.

Manifests and the Request Math Nobody Mentions

In a live stream, the media playlist changes every few seconds. A simplified live HLS playlist with an ad marker looks like this:

Live HLS media playlist (simplified)
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:18432
#EXT-X-PROGRAM-DATE-TIME:2026-04-12T14:32:08.000Z
#EXTINF:4.000,
seg_18432.m4s
#EXTINF:4.000,
seg_18433.m4s
#EXT-X-CUE-OUT:DURATION=30
#EXTINF:4.000,
ad_slot_18434.m4s

Every player re-fetches this file roughly every target duration. At 25M viewers that is millions of requests per second for a file that is identical for everyone (per rendition and language). The design consequences:

  • Cache manifests at the CDN with a TTL of about half the segment duration (e.g. 1 to 2 s). The edge serves millions of requests from one cached copy.
  • Request collapsing at edges and shields: when the cached manifest expires, only one request per edge goes upstream; others wait for it.
  • Segments are immutable once published; cache them with long TTLs (the DVR window).
  • Personalised manifests destroy caching. This matters enormously for ads, next section.
  • Program date time tags let players align playback with wall-clock time, which is how you synchronise latency across devices and the scorecard with video.

CDN Strategy and Pre-Scaling

At ~30 Tbps, CDN capacity is a negotiated, scheduled resource, not an elastic one.

  • Capacity reservation: forecast peak concurrency per region and ISP for each match, then reserve capacity with each CDN partner days in advance. CDNs themselves pre-position servers and bandwidth for known events.
  • Multi-CDN with steering: a control plane assigns each session a CDN based on region, ISP, real-time QoE (startup time, error rate, throughput from player telemetry) and remaining reserved capacity. Players can fail over mid-stream to another CDN's URL for the next segment.
  • ISP-embedded caches: caches inside Jio, Airtel and Vi networks serve traffic without crossing peering links, which are often the real bottleneck during a big match.
  • Origin shield + collapsing: for a live stream, the working set is tiny (the last few segments per rendition and language), so hit ratios are extremely high, provided misses are collapsed.
  • Bitrate as a capacity lever: if a region approaches its capacity limit, cap the maximum rendition there (e.g. 720p instead of 1080p) via the steering or manifest layer. A slightly softer picture for some is better than buffering for everyone.

Scaling Backends Ahead of the Spike

Reactive autoscaling (scale when CPU exceeds 70%) fails for live sports. Instances take minutes to boot, pull images, warm caches, open connection pools and pass health checks, while traffic can jump by millions of users within a minute when something dramatic happens. Hotstar engineers have publicly described scaling on concurrency forecasts rather than CPU for exactly this reason.

The pre-scaling playbook

  1. Forecast concurrency per match from history: teams playing, stage of tournament, day and time, star players, previous matches' curves.
  2. Translate concurrency to capacity per service using measured requests-per-viewer and per-instance throughput from load tests.
  3. Scale before the toss to the level for the next stage of the match, with lead time; keep the ladder one step ahead.
  4. Do not scale down mid-match. A lull after a wicket can turn into a surge 10 minutes later.
  5. Use concurrency as the scaling signal (from player heartbeats), not CPU, for any reactive top-up.
  6. Keep warm pools of pre-initialised instances and make sure cloud capacity (and quotas) is actually available in the region; capacity reservations exist for this.
Python: turning a concurrency forecast into a scaling plan
import math

def scaling_plan(forecast, rps_per_viewer, rps_per_instance, headroom=1.5, lead_min=15):
    """forecast: list of (minute_offset, expected_concurrent_viewers).
    Returns (minute_to_start_scaling, target_instances) steps, issued lead_min early
    because instances take minutes to boot, warm caches and pass health checks."""
    plan = []
    for minute, viewers in forecast:
        needed = viewers * rps_per_viewer * headroom / rps_per_instance
        plan.append((minute - lead_min, math.ceil(needed)))
    # never scale down during the match: surges come back at the next wicket
    peak_so_far, out = 0, []
    for minute, n in plan:
        peak_so_far = max(peak_so_far, n)
        out.append((minute, peak_so_far))
    return out

# Toss at T+0, first ball at T+30, expected death-overs peak at T+180
forecast = [(0, 5_000_000), (30, 12_000_000), (120, 18_000_000),
            (180, 25_000_000), (200, 15_000_000)]
for start, n in scaling_plan(forecast, rps_per_viewer=0.05, rps_per_instance=2_000):
    print(f"T{start:+d} min -> {n} API instances")
# T-15 min -> 188 API instances
# T+15 min -> 450 API instances
# T+105 min -> 675 API instances
# T+165 min -> 938 API instances
# T+185 min -> 938 API instances

In Kubernetes terms, this becomes scheduled updates to replica counts (or HPA minimums) plus cluster node pre-provisioning; see Docker and Kubernetes for backend engineers. The essential idea is that capacity is a function of the match schedule, decided in advance and validated by load tests at full forecast scale.

Avoid self-inflicted surges

  • Login storms: long-lived sessions so returning viewers do not all re-authenticate; entitlement checks cached in signed tokens rather than queried per segment.
  • Client retries with jitter and backoff: a 5-second API blip must not turn into 25M synchronised retries.
  • Push notifications: "Kohli is on 99" sent to 50M users creates the surge you are trying to survive. Stagger sends over minutes, by cohort.
  • Home screen: during a live match, the home page can be a mostly static, CDN-cached response with the match card on top.

Ad Insertion at Every Over Break

CSAI vs SSAI

Client-side (CSAI)Server-side (SSAI)
HowPlayer pauses content, calls ad server, plays ad with separate playerAd segments stitched into the stream manifest; player sees one stream
ExperienceVisible switching, possible blank/bufferingSeamless, TV-like
Ad blockersEasier to blockHard to block
Scale challenge25M clients call the ad server simultaneouslyManifest personalisation breaks CDN caching

Making SSAI scale: cohorts and pre-computed decisions

  • Cohort manifests: instead of a unique manifest per viewer, group viewers into cohorts (e.g. city × language × device × a few targeting segments, maybe a few thousand cohorts). Each cohort gets its own manifest variant, cacheable at the CDN. Targeting is slightly coarser; caching works.
  • Pre-computed ad decisions: the SCTE-35 markers tell you a break is coming. Before each break, the ad decision service computes the pod (sequence of ads) for every cohort, respecting campaign pacing, frequency caps and sponsor commitments, so nothing needs deciding at the instant the break starts.
  • Pre-transcoded creatives: ads are transcoded into the same ladder, codecs and segment boundaries as the live stream ahead of time and pre-warmed in CDNs; an ad that has to be transcoded on demand will miss the break.
  • Tracking beacons: impression and quartile events from 25M viewers per break are batched on the client and sent with jitter to a collector that writes to Kafka; billing aggregates them downstream (the same pattern as ad click aggregation).
  • Fallback: if the ad system is late or down, the stream must continue: fill the slot with a default sponsor slate or the broadcaster's own break content. Never stall playback waiting for an ad.

Graceful Degradation: The Panic Button

When load exceeds capacity, the worst outcome is uniform failure. The best outcome is that video keeps playing for everyone while lower-priority features turn off. Define a ladder in advance, wire every level to a feature flag that clients read from a CDN-cached config, and rehearse it.

LevelTrigger (example)Actions
0 NormalEverything healthyAll features on
1 ElevatedBackend latency risingDisable personalised recommendations (serve static rows), increase API cache TTLs, slow telemetry frequency
2 HighSustained overloadSample social reactions (show aggregates, not every emoji), disable comments, freeze non-match home content, stop non-critical background calls
3 CriticalCDN or core APIs near limitsCap max bitrate per region, skip non-essential ad personalisation (use default pods), serve entitlement from cached tokens only
4 SurvivalPartial outageStatic match page from CDN, playback-only mode, retry-after hints to clients

Design principles behind the ladder:

  • Classify every API as critical (playback, entitlement), important (scorecard, ads) or optional (recommendations, social, profile edits).
  • Clients must tolerate missing features: a failed recommendations call renders an empty row, not an error screen.
  • Static fallbacks for every critical screen, pre-generated and cached at the CDN.
  • Per-dependency timeouts and circuit breakers so one slow service cannot hold threads needed by playback.

Scorecard, Key Moments and Reactions

Real-time features are where candidates over-engineer. Opening 25M WebSocket connections just to push a scorecard is expensive and fragile.

  • Scorecard as a cached JSON: the score service publishes a small JSON per match, cached at the CDN with a 1 to 2 second TTL; clients poll it with jitter. 25M polls every few seconds become mostly edge hits.
  • Sync with video, not wall clock: because the stream is delayed, showing "SIX!" from the scorecard before the video shows it is a spoiler. Tag score updates with the program date time of the ball and let the player reveal them when playback reaches that timestamp.
  • Reactions and polls: clients send events in batches; a stream processor aggregates counts per few seconds; the aggregate is published like the scorecard. Nobody needs every individual emoji, only the swelling totals. Leaderboard-style features for fantasy contests use the patterns in real-time leaderboard design.
  • Key moments and highlights: operators (or ML models) mark timestamps; a clipping service cuts segments from the DVR window into a short on-demand asset within minutes, no re-encoding needed when cuts align to segment boundaries.

Quality-of-Experience Monitoring

Server metrics alone do not tell you if people can watch. Player telemetry is the ground truth.

  • QoE metrics: video start time, startup failures, rebuffering ratio, average and distribution of bitrate, playback errors, live latency, by CDN × ISP × region × device × app version.
  • Real-time dashboards with second-level granularity during matches; alerts on deviations from the expected concurrency curve (a sudden drop means a failure, not disinterest).
  • Automated actions: the CDN steering system shifts traffic away from a CDN-ISP pair whose rebuffering rate spikes, within a minute, without human intervention.
  • Synthetic probes from many cities and ISPs playing the stream continuously.
  • War room: big matches run with a staffed command centre, pre-agreed runbooks and owners for each degradation lever.

For the general telemetry stack (metrics, logs, traces), see observability explained.

Interview Guide

A 45-minute structure

  1. Clarify: live only or VOD too? Latency target? Languages? Ads? (3 min)
  2. Estimate: egress Tbps, segment and manifest request rates, ad decisions per break. (5 min)
  3. Pipeline: contribution, transcode, package, origin, shield, multi-CDN, with redundancy. (10 min)
  4. Latency: classic vs low-latency HLS and the trade-offs. (5 min)
  5. Surges: pre-scaling, CDN reservation, avoiding self-inflicted storms. (8 min)
  6. Ads: SSAI with cohorts and pre-computed decisions. (6 min)
  7. Degradation and monitoring. (8 min)

Follow-ups to expect

  • "How is this different from Zoom?" Zoom is many-to-many with sub-second latency over WebRTC and SFUs; Hotstar is one-to-many where seconds of latency are acceptable and HTTP caching does the heavy lifting. See Zoom design.
  • "What if the primary ingest region fails mid-over?" The second chain is already producing timestamp-aligned segments; the origin or CDN switches source, players continue with at most a brief glitch.
  • "How do you test for 25M users?" Load testing with distributed generators that emulate real player behaviour (manifest polling, ABR switching, API calls), run against production-like infra before the season, plus chaos drills.
  • "How would you cut bandwidth cost?" Per-device ladders, better codecs (HEVC/AV1) where devices support them, regional bitrate caps during peaks, and ISP-embedded caches that reduce transit cost.

Common mistakes

  • Treating it as on-demand YouTube and spending time on upload pipelines.
  • Relying on reactive autoscaling for event-driven surges.
  • Per-user manifests for ads without addressing CDN cacheability.
  • Pushing every scorecard update and emoji over WebSockets to 25M clients.
  • No redundancy in contribution and encoding: a single encoder is a single point of failure for the entire audience.
  • No plan for degradation; "the system is scaled" is not a plan.
✅
The framing that impresses"Video bytes are a solved CDN problem if we reserve capacity and cache manifests well. The real risks are synchronised surges: viewers returning at a key moment, ad breaks, push notifications, retries. So I'll pre-scale from a forecast, make every client behave politely under failure, and keep a rehearsed degradation ladder that protects playback above all else."

To round out your video preparation, compare this with Instagram Reels, where the challenge flips to many different videos and per-swipe startup.

Frequently Asked Questions

How does Hotstar handle millions of concurrent viewers?▾
Video segments are served almost entirely from CDNs, including caches inside ISP networks, with capacity reserved in advance of big matches. Backend APIs are scaled up ahead of predicted traffic rather than reactively, clients are designed to back off and cache aggressively, and non-essential features are switched off under load so core playback keeps working.
Why is live streaming delayed compared to TV?▾
Traditional HLS uses segments of several seconds and players buffer multiple segments before playing, which adds 20 to 30 seconds or more on top of encoding and distribution delay. Low-latency HLS and chunked CMAF reduce this to a few seconds by delivering partial segments as they are encoded, at the cost of tighter buffers and more requests.
What is server-side ad insertion (SSAI)?▾
SSAI stitches ad segments directly into the video stream's manifest on the server, so the player sees one continuous stream. It is harder for ad blockers to skip, gives a smoother TV-like transition, and works on devices with limited player logic, but it requires per-user or per-cohort manifests and careful scaling at every ad break.
Why can't autoscaling handle IPL traffic spikes?▾
Reactive autoscaling waits for metrics like CPU to rise, then takes minutes to launch instances and warm them up, while concurrency can jump by millions within a minute or two when a key moment happens. Platforms therefore pre-scale to forecast levels before the match and keep capacity high until it ends.
Which protocol is used for live sports streaming in India?▾
Adaptive HTTP streaming, mainly HLS and MPEG-DASH, often with CMAF segments, delivered over CDNs. Ingest from the production facility to the cloud commonly uses contribution protocols such as SRT, RTMP or dedicated links, with redundant paths.
What is graceful degradation in system design?▾
Graceful degradation means the system deliberately sheds less important functionality under stress so the most important function keeps working. For live streaming that can mean disabling personalised recommendations, sampling social reactions, capping maximum video quality and serving static fallbacks, so that playback continues for everyone.
What is the difference between designing YouTube and designing Hotstar live?▾
On-demand video can be transcoded once and cached over time, and viewers are spread across a huge catalog. Live sports means one stream watched by everyone at the same moment, real-time encoding with strict latency, synchronised surges driven by match events, and ad breaks that hit every viewer simultaneously.

Master Large-Scale System Design

Prepflix's system design course covers Hotstar, YouTube and Zoom-scale streaming designs with capacity drills and mock interviews run by engineers from top product companies.

Explore the Prepflix Course →
Pranjal Jain
Pranjal Jain

Ex-Microsoft SDE · IIT Kanpur · Founder of Prepflix. Helps engineers crack startup and product company interviews across India.