Design Live Stream Polls

Medium35 min
1 / 30
understanding7 min read

Problem Statement and Live Poll Context

How Problem Statement and Live Poll Context (understanding) informs Live Stream Polls architecture and interviewer depth.

Problem Statement and Live Poll Context

Problem framing

Twitch, YouTube Live, and TikTok LIVE let creators run timed polls on top of video. Viewers vote from mobile or web while chat and donations continue. The product goal is sub-second perceived updates on the overlay without overloading the video CDN path.

Design choices
  1. Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version
  2. Votes are idempotent on (user_id, poll_id) using client vote_uuid
  3. Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB
  4. Result fan-out uses WebSocket room channels keyed by stream_id
  5. Blind mode hides percentages until close when creators want suspense
Deep dive

Walk from creator dashboard through poll publish, vote ingest API, Kafka partition by poll_id, aggregator workers bump HINCRBY counters, gateway pushes poll_state deltas to every connected viewer. Quantify p95 overlay latency under 500ms and peak vote bursts during viral raids.

javaOne Dark Pro
1public final class PollVote {
2 private final String pollId;
3 private final String userId;
4 private final String optionId;
5 private final long pollVersion;
6
7 public PollVote(String pollId, String userId, String optionId, long pollVersion) {
8 this.pollId = pollId;
9 this.userId = userId;
10 this.optionId = optionId;
11 this.pollVersion = pollVersion;
12 }
13
14 public boolean matchesActiveWindow(long activeVersion) {
15 return pollVersion == activeVersion;
16 }
17}
pythonOne Dark Pro
1from dataclasses import dataclass
2
3@dataclass(frozen=True)
4class PollSnapshot:
5 poll_id: str
6 option_counts: dict[str, int]
7 poll_version: int
8 status: str
9
10def should_apply_delta(local: PollSnapshot, incoming: PollSnapshot) -> bool:
11 return incoming.poll_version > local.poll_version
typescriptOne Dark Pro
1interface PollSnapshot {
2 pollId: string;
3 optionCounts: Record<string, number>;
4 pollVersion: number;
5 status: "draft" | "active" | "closed";
6}
7
8export function mergePollState(
9 local: PollSnapshot,
10 incoming: PollSnapshot,
11): PollSnapshot {
12 if (incoming.pollVersion <= local.pollVersion) return local;
13 return incoming;
14}
Interviewer positioning

Assume 30M DAU, 8% of live viewers see an active poll, 15% of those vote within 60 seconds. Peak concurrent viewers on a top stream can exceed 500K.

  • Appendix note 1: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 2: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 3: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 4: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 5: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 6: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 7: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 8: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 9: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 10: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 11: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 12: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 13: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 14: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 15: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 16: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 17: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 18: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 19: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 20: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 21: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 22: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 23: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 24: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 25: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 26: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 27: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 28: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 29: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 30: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 31: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 32: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 33: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 34: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 35: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 36: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 37: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 38: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 39: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 40: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 41: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 42: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 43: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 44: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 45: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 46: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 47: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 48: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 49: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 50: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 51: Votes are idempotent on (user_id, poll_id) using client vote_uuid, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 52: Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 53: Result fan-out uses WebSocket room channels keyed by stream_id, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 54: Blind mode hides percentages until close when creators want suspense, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.
  • Appendix note 55: Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version, idempotent vote_uuid, blind results mode, and stream room fan-out for problem-statement-and-live-poll-context.

Why interviewers care

Live Stream Polls interviews reward crisp scope, explicit trade-offs, and failure stories—not generic microservice diagrams.

Interview checkpoint

Name one failure story for Problem Statement and Live Poll Context that proves you understand real outages, not happy-path diagrams.

Key Highlights

  • Poll lifecycle is stream-scoped: draft, active, closed with monotonic poll_version
  • Votes are idempotent on (user_id, poll_id) using client vote_uuid
  • Hot tallies live in Redis; durable totals land in Cassandra or DynamoDB
Interview tip
State early that video bytes stay on the CDN; polls are a lightweight metadata plane. Interviewers at Twitch/YouTube care about hot-stream isolation.
Mention this
Say AP for live percentages, CP authoritative tally at poll close, and idempotent vote_uuid for at-least-once clients.

Section Rescue Kit

Buzzwords to use:

Idempotent votepoll_state fan-out

Safe statements:

  • "I will size vote ingest separately from video CDN bandwidth before picking storage."
  • "Let me walk through poll close as a strongly consistent boundary event."
Design Live Stream Polls - System Design | WinJob | WinJob