Twitch / Live Streaming#
Problem statement (interviewer prompt)
Design Twitch (or YouTube Live): streamers ingest via RTMP/SRT, live transcode into multiple bitrates, deliver to viewers via LL-HLS at 2-5s glass-to-glass, support 100k concurrent streams + 10M concurrent viewers per event, plus real-time chat with mod tooling.
flowchart LR
S([Streamer])
ING([RTMP / SRT Ingest])
TR([Live Transcoder])
PKG[HLS / LL-HLS Packager]
CDN
V([Viewer])
CHAT[Chat - IRC-like]
S --> ING --> TR --> PKG --> CDN --> V
V <--> CHAT
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class S,V client;
class PKG,CHAT service;
class ING,TR compute;
flowchart TB
subgraph Streamer
OBS[OBS / Studio]
end
subgraph Ingest
RTMP([RTMP / SRT / WHIP Ingest])
AUTH[[Stream key auth]]
REGION[Region anycast]
EDGE_ING([Ingest edge nodes])
end
subgraph Transcode[Live Transcode]
SHARD[[Stream sharding<br/>per channel]]
GPU([GPU-accelerated encoders<br/>NVENC / Quick Sync])
LADDER[Ladders 1080p60 / 720p / 480p / 360p / 160p]
CODEC[H.264 / HEVC / AV1 incremental]
TS[Timestamp / PTS alignment]
end
subgraph Packaging
HLS[LL-HLS / DASH packager]
CMAF[CMAF chunked / fMP4]
KEY[DRM keys - sub-only streams]
end
subgraph Delivery
CDN[Twitch CDN<br/>Amazon CloudFront + own POPs]
PLAYER[Player ABR]
end
subgraph Chat[Chat Plane - separate]
WS[WebSocket gateway<br/>IRC-derived]
CHAN[[Channel pub/sub]]
MOD[AutoMod / mods bots]
BITS[Bits / cheers / subs]
end
subgraph VOD[VOD / Clips]
REC[Recorder]
CLIPS([Clip generator])
VODS[(VOD store)]
end
subgraph Discovery
HOME[Home / Following]
CAT[Categories / Games]
SEARCH[Search]
NOTIF[Live notifications]
REC2([Recommendations])
end
subgraph Monetization
SUBS[Subscriptions]
BITS2[Bits / virtual goods]
ADS[Ad insertion - SCTE-35]
AFFIL([Affiliate / Partner programs])
end
subgraph Realtime
PRES([Concurrent viewer count])
PRED[Predictions]
POLLS[Polls]
INTERACT[Channel points]
end
OBS --> RTMP --> EDGE_ING --> SHARD --> GPU --> LADDER --> HLS --> CMAF --> CDN
CDN --> PLAYER
PLAYER --> Viewer
OBS --> AUTH
Viewer --> Chat
Chat --> CHAN
Chat --> MOD
Chat --> Realtime
Chat --> Monetization
Transcode --> REC --> VODS
Viewer --> Discovery
Discovery --> REC2
Ads --- Packaging
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class AFFIL,PRES client;
class REGION,CDN,WS edge;
class OBS,LADDER,CODEC,TS,HLS,CMAF,KEY,PLAYER,MOD,BITS,REC,HOME,CAT,SEARCH,NOTIF,SUBS,BITS2,ADS,PRED,POLLS,INTERACT service;
class VODS datastore;
class AUTH,SHARD,CHAN queue;
class RTMP,EDGE_ING,GPU,CLIPS,REC2 compute;
Latency targets#
- Default HLS: 5-15 s glass-to-glass.
- Low-latency HLS / LL-DASH: 2-4 s.
- WebRTC ultra-low: < 1 s (Twitch experimental, used in Stream Chat with hosts).
Ingest distribution#
- Anycast routes streamer to nearest ingest POP.
- Stream key authentication + abuse filtering.
- Stream replicated across availability zones to survive ingest failure.
Chunked encoding#
- CMAF chunked → start producing the next chunk while encoding.
- Player can fetch partial chunks (LL-HLS) for sub-second.
Chat scale#
- IRC-derived protocol; one channel can have 200k+ concurrent viewers chatting.
- Sharded by channel; fan-out via pub/sub topic per channel.
- AutoMod and moderators in the loop.
Monetization#
- Subscriptions, Bits, ads via SCTE-35 markers, affiliate revenue.
- Stream events (sub, raid, follow) emitted to overlays via WebSocket.
Glossary & fundamentals#
Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.
| Tag | Concept | What it is | Page |
|---|---|---|---|
HLD |
Load balancer / GSLB | L4/L7 traffic distribution and failover | load-balancer |
HLD |
CDN | edge caching for static assets | cdn |
HLD |
Sharding | horizontal partitioning across nodes | database-sharding |
HLD |
Pub/Sub & message brokers | topics, consumer groups, delivery semantics | pub-sub-pattern |
HLD |
Leader/follower replication | sync/semi-sync/async replication, failover | replication-leader-follower |
HLD |
Realtime protocols | WS / SSE / polling / gRPC streaming | realtime-protocols |
LLD |
Async models | futures / async-await / coroutines / actors | async-models |
Quick reference#
Functional#
- Live ingest from streamers; transcode + ABR delivery.
- Real-time chat with mods + bot ecosystem.
- VOD recording and clips.
- Subscriptions, bits, ads.
- Channel discovery + recommendations.
Non-functional#
- Glass-to-glass latency 2-5 s (LL-HLS) or sub-second (WebRTC paths).
- Concurrent streams: 100k+ live.
- Concurrent viewers: 10M+ on big events.
- 99.9% ingest availability.
Capacity#
- Each streamer ingest: 6-10 Mbps × 100k streams = 1 Tbps ingest.
- Egress at peak: tens of Tbps.
- VOD storage: hundreds of PB.
Schema#
streams(channel_id, started_at, ingest_node, encodes[], status)chat_messages(channel_id, user_id, ts, text, flags)(transient + archive)vods(id, channel_id, started_at, duration, segments[])clips(id, vod_id, start, end, creator_id)
Trade-offs#
- Cloud + own POPs: own POPs near gaming PoPs reduce streamer latency.
- Latency vs reliability: lower latency = smaller buffers = more rebuffering.
- Per-stream transcoding is the dominant cost; not every stream gets full ladder (low-viewer streams stay source-only).
Refs#
- Twitch engineering blog (Mixer, live transcoding, chat at scale), Amazon Interactive Video Service (IVS) docs, YouTube Live papers, "Low-Latency HLS" Apple spec, ByteByteGo "Design live streaming".
FAQ#
How does Twitch achieve 2 to 5 second glass to glass latency?#
Low Latency HLS uses CMAF chunked encoding so the packager publishes partial chunks while the encoder is still processing. Players fetch partial segments to drop end to end delay under five seconds.
How does Twitch chat scale to hundreds of thousands of viewers per channel?#
Chat uses an IRC derived WebSocket protocol sharded by channel, with fan out via a pub sub topic per channel. AutoMod and moderator bots filter messages in line before broadcast.
How does Twitch ingest streams from creators?#
Streamers push RTMP, SRT, or WHIP to the nearest ingest POP via anycast routing. A stream key authenticates the channel and the stream is replicated across availability zones for failover.
Why does not every Twitch stream get a full bitrate ladder?#
Per stream transcoding is the dominant cost. Low viewer streams are kept at source resolution only, while popular streams get the full 1080p, 720p, 480p, 360p, and 160p ladder.
How does Twitch monetize live streams?#
Revenue comes from subscriptions, Bits and cheers, virtual goods, and ad insertion via SCTE-35 markers. Affiliate and Partner programs share revenue with creators based on stream metrics.