Learning pathsA
GUIDED PRACTICE

Practice: FB Live Comments

Design a comment stream for live videos, including durable posting, fast fanout, reconnect, and moderation.

Design a comment stream for live videos, including durable posting, fast fanout, reconnect, and moderation.

Write your own design before opening hints or the solution review. The numbers below are exercise assumptions, not claims about any company’s production traffic. You may challenge an assumption, but record the replacement and explain which decision changes.

Scenario and constraints

  • Typical room: 100 viewers; largest room: 100,000 viewers.
  • Largest room receives 100 comments/s at 500 bytes/event.
  • Target visible updates within one second under normal conditions.
  • Retain replay history for one hour in this exercise.

Your deliverables

  • Define accepted-comment and displayed-comment guarantees separately.
  • Specify a room-scoped event cursor and client deduplication behavior.
  • Calculate largest-room raw fanout bandwidth and place its bottleneck.
  • Show a bounded slow-client buffer and an explicit reset response.

Reason about this sequence

Gateway sends cursor 52 → Connection drops → Client reconnects after 51 → Replay includes 52 → Client dedupes and resumes
Scroll to inspect the diagram, or open it at full size.

Figure — Gateway sends cursor 52 → Connection drops → Client reconnects after 51 → Replay includes 52 → Client dedupes and resumes

For every step, annotate what is durable, what the caller knows, and which identity survives a retry. Identify the point where two concurrent actors could disagree. Do not assume a timeout means failure or a cache value grants ownership.

Interviewer follow-ups

  • A gateway crashes immediately after sending an event.
  • A viewer returns with a cursor older than one hour.
  • Moderation removes a comment already cached on clients.

Answer each follow-up using the same design first. If it breaks, change the smallest boundary that repairs the invariant and explain the new cost. Show whether the change adds latency, storage, coordination, or operational work.

Staged hints

Hint 1 — reveal

Answer: Hint 1 — A socket is a delivery attempt, not a durable mailbox. Start by deciding where a disconnected client can recover the last hour of events.

Hint 2 — reveal

Answer: Hint 2 — After durable acceptance, publish to a room distribution tier. Gateways own client connections and subscribe only to rooms they serve. A fanout tree or broker layer prevents one producer from directly writing to a million sockets. Measure bytes per comment times viewers, not just comments posted per second.

Hint 3 — reveal

Answer: Hint 3 — A gateway crashes after forwarding an event but before the client records its cursor. The reconnect replay includes that event again. Client deduplication avoids showing it twice. Conversely, if the client records a cursor before applying an event, it may skip content. Define the client apply-and-cursor sequence and test network flaps, delayed removals, and history expiry.

Evidence-based self-review

  • Durable acceptance precedes the claimed success response.
  • The fanout design accounts for viewers times event rate.
  • Reconnect handles both overlap and expired history.
  • Moderation and authorization apply across live and history paths.

Score each item 0 if absent, 1 if named without an enforceable mechanism, or 2 if the mechanism and a failure are explained. Record evidence from your own diagram beside the score. Then choose one weak decision, revise it, and repeat the relevant follow-up. This rubric is a learning tool, not a hiring forecast.

Reveal the full worked solution

Save your attempt before continuing. ## Interview scope and guarantees

Post comments to a live event, display recent comments with low delay, reconnect without duplicates, and remove moderated content. Ordering is per stream or shard, not necessarily global across the service. Slow consumers must not stall the broadcaster.

Capacity worksheet

Assume one event has 1 million viewers and 1,000 comments/s. Sending every 200-byte comment to every viewer would be 200 GB/s before protocol overhead. That product expectation is often unnecessary; offer a moderated or sampled view, batch updates, and define what each viewer receives.

Concrete API contract

Contract / pseudocode
POST /streams/{id}/comments {clientId,text} -> {commentId,sequence}
GET /streams/{id}/comments?after=...
SSE /streams/{id}/events?cursor=...
DELETE /comments/{id} -> moderation event

Data model and access paths

Contract / pseudocode
comments(stream_id,sequence,comment_id,author_id,text,state)
stream_offsets(stream_id,partition,offset)
moderation(comment_id,version,state)
client_dedup(author_id,client_id,comment_id)

Evolve a solution and explain each change

Three architecture decisions for FB Live Comments, including the pressure each introduces.
Scroll to inspect the diagram, or open it at full size.

Figure — Three architecture decisions for FB Live Comments, including the pressure each introduces.

Step 1: Append comments

Authenticate the author and append a stream-scoped comment ID. Per-viewer polling wastes work and does not define replay.

Step 2: Push bounded streams

Fan out persisted comments over session connections with resume cursors. Slow viewers can accumulate unbounded buffers.

Step 3: Handle hot broadcasts

Shard fanout delivery, filter moderation changes, and shed overload predictably. Delivery shards do not automatically create a global comment order.

Responsibility overview

Connected responsibilities for FB Live Comments. Trace the authoritative and derived paths separately.
Scroll to inspect the diagram, or open it at full size.

Figure — Connected responsibilities for FB Live Comments. Trace the authoritative and derived paths separately.

Worked end-to-end scenario

A viewer posts c20 and disconnects before the response. Retrying the client comment ID returns the stored comment. Broadcast subscribers receive c20 through fanout workers, but a slow phone fills its buffer. Rather than accumulating unlimited memory, send a resync signal or disconnect according to policy. The phone reconnects with its stream cursor and fetches a bounded persisted range. A moderator removes c20. The system emits a tombstone or removal event; reconnect replay must not resurrect it. A hot stream can use several delivery shards while one ordered ingest partition assigns stream positions.

Why these access paths matter

Persist by broadcast ID and stream position. Deduplicate author/client IDs and index moderation state. Connection registries map broadcast shards to active sessions; they are ephemeral delivery state, not authoritative history. If sampled comments are allowed under overload, state that separately from full replay and make the client aware of gaps.

Build the baseline first

FB Live Comments: baseline request paths.
Scroll to inspect the diagram, or open it at full size.
  1. Comment API → durable append → ordered stream.
  2. Fanout service → connection gateway → viewers.
  3. Reconnect cursor → retained history → live handoff.

Evolve the design under load

FB Live Comments: additional scaling and recovery paths.
Scroll to inspect the diagram, or open it at full size.
  1. Stream partitions → regional fanout tree.
  2. Gateway batches → bounded client buffers.
  3. Moderation event → removal projection → clients.

Defend the hardest decision

An append log preserves a resumable position. Gateways subscribe once per popular stream and fan out locally, rather than establishing one broker subscription per viewer. A client that cannot keep up receives a bounded backlog or a reset-to-latest instruction. If the system samples comments, the UI must not imply a complete ordered transcript. A cursor should encode the shard positions needed to resume a partitioned stream.

Failure and recovery analysis

After a disconnect, subscribe to the live stream while fetching history with a defined high-water mark, then deduplicate the overlap. Fetching history first and subscribing later creates a gap. A moderation deletion must suppress future replay and update connected clients; removing only the database row leaves already-buffered copies visible.

Security and privacy boundary

Rate-limit authors, escape rendered content, and preserve moderator audit trails without leaking removed text to unauthorized readers.

Interview follow-ups with reasoning

Question: Can SSE replace WebSockets?

Show answer and explanation

Answer: Yes for server-to-browser updates while posting uses HTTP.

Question: How do you handle a viral stream?

Show answer and explanation

Answer: Split fanout work across regions and gateways while protecting the append authority.

Question: What do you measure?

Show answer and explanation

Answer: Publish-to-display lag, slow-client drops, reconnect gaps and moderation propagation delay.

Operate and verify the design

Publish-to-display delay, slow-client drops, replay resets and moderation lag.

Reconnect a viewer during a burst and verify the history/live handoff has no unexplained gap.

A second scenario to test transfer

A room receives 100 comments/s and has 100,000 viewers. At an illustrative 500 bytes per delivered event, raw fanout is 5 GB/s before protocol overhead. The storage write rate is modest compared with delivery bandwidth. A popular-room tier can batch or sample display events under a stated UX policy while preserving accepted comments in history. Adding database replicas alone does not solve socket fanout.

A reconnect cursor is older than retained events. What should the server return?

Show answer and explanation

Answer: An explicit reset/snapshot requirement with a new valid cursor. Silently starting at the newest event would hide a gap. The UI can show a recent window and disclose that earlier live history is unavailable.

Compare alternatives

ConcernMechanismTrade-off
Hot roomHierarchical fanoutMore routing state
Slow deviceBounded buffer + resumeMay need snapshot reset
ModerationRemoval events + authoritative historyPropagation delay
OrderingRoom-scoped cursorNo global ordering promise

A design-changing exercise

A fanout node crashes after accepting a comment. Is the comment lost?

Show answer and explanation

Answer: Not if acceptance meant durable log insertion. Delivery can be reconstructed from the log and subscriber cursors; memory-only fanout is not enough.

Design workshop: replay-to-live without gaps

Core scope is posting, recent history, live viewing and moderated removal for one broadcast. Ranking every historical comment is excluded. Choose live delivery p95 under one second under admitted load, durable accepted comments and a 30-minute replay window. Popular-room display sampling, if enabled, is disclosed; it does not delete accepted history.

CONNECT /streams/id/comments accepts afterCursor. Events include streamId, sequence, commentId, type, contentVersion and payload. A cursor binds stream and position; a cursor for another stream is rejected. If it precedes retention, return reset_required with a recent snapshot and new cursor. Never silently return only newest events while pretending the suffix is complete.

Subscribe to live output, capture durable high watermark H, fetch (cursor,H], then consume live output after H. Buffer/overlap may repeat events, so deduplicate by stream/sequence. A bounded buffer overflow during handoff aborts and requires another replay. Attaching after a historical query without a watermark can lose the events between those steps.

A cursor 40 joins a stream at watermark 43. Viewer to Gateway: Resume after 40; Gateway to Room fanout: Subscribe with bounded buffer; Gateway to Durable log: Read high watermark H=43 and suffix 41..43; Room fanout to Gateway: Buffered event 43 then 44; Gateway to Viewer: Deliver 41,42,43; drop overlap 43; deliver 44; Gateway to Viewer: Persist/ack last delivered cursor 44
Scroll to inspect the diagram, or open it at full size.

Figure — A cursor 40 joins a stream at watermark 43.

A room log assigns sequence under one ordered append authority. Fanout delivery is then sharded across gateway groups; delivery-shard IDs are not a room-wide order. A session registry maps room→gateway populations and expiring sessions. Root fanout distributes batches to regional workers, then gateway groups, then bounded per-socket queues. Persisted history stays independent of session presence.

Fanout budget for a hot broadcast. 1,000 comments/s × 1M viewers × 200 bytes / 200 GB/s raw payload / Network hierarchy, not only DB scaling; 100,000 sockets × 8 KiB buffer / 819 MB buffer payload / Connection metadata adds more memory; Batch 20 events over 20 ms / One envelope per batch / Bound latency; reduce protocol overhead; Slow socket exceeds buffer / Reset and recent snapshot / Do not allocate unlimited memory
Scroll to inspect the diagram, or open it at full size.

Figure — Fanout budget for a hot broadcast.

Sample display at a gateway only under a product contract that labels the stream as selected comments. Preserve ordering among delivered events and carry a cursor over skipped ranges so resume semantics are explicit. Full-history clients query the durable log, not the sampled socket stream. Backpressure can reject new writes with 429 under overload or accept durably and signal delayed delivery; choose the boundary honestly.

Moderation appends a versioned removal event for comment C. Clients apply newer content versions and retain a bounded tombstone so a delayed create cannot resurrect C. Reconnect snapshots exclude removed content. A moderator can race with publication; authorization and policy checks happen at the write authority and renderer. Report moderation propagation lag separately from accepted-comment latency.

Exercise: Live output is subscribed at time T, the historical query returns through 43, and events 43/44 are buffered. What is sent?

Show answer and explanation

Answer: History through 43, then only buffered events strictly after 43. If the buffer overflows, restart from a supported durable cursor rather than skip to the latest event.

Technical references

Kafka processing and external-sink boundaries.

PostgreSQL transaction isolation and concurrent updates.

30:00Self-guided practice timer
The timer resets when you leave this page. Save your design separately.
Your challenge

A reconnect cursor is older than retained events. What should the server return?

Your design draft

Clarify assumptions, explain your approach, and test the difficult cases. Save your draft, then compare it with the study notes.

Open solution review

Self-review checklist

Self-guided practice. Automated AI feedback and code execution are not connected.