Discussion Platform
Support text posts, threaded replies, voting and community feeds with predictable moderation and hot-thread behavior.
Support text posts, threaded replies, voting and community feeds with predictable moderation and hot-thread behavior. This worked design targets SDE-2; the scale figures below are exercise assumptions, not claims about a named company's implementation.
Clarify the prompt
| Ask the interviewer | Decision to record |
|---|---|
| Forum communities, follower feeds or both? | Start with community threads and ranked discovery. |
| Can users edit/delete posts, and what happens to replies? | |
| How strict must vote totals, moderation removal and feed freshness be? |
Requirements and scope
The core deliverable is: Support text posts, threaded replies, voting and community feeds with predictable moderation and hot-thread behavior. The first design implements the APIs below and the state constraints in the data model. Agree the latency, freshness, retention and failure policy before adding infrastructure. Every successful acknowledgment must have an explicit meaning: accepted intent, committed state or completed external work. These are separate milestones.
Capacity and bottleneck reasoning
Assume ten million daily users, 20 feed views each and one million posts/day: about 2,315 feed reads/s and 12 post writes/s average. A viral thread can dominate a single partition; reply fanout and vote counters need independent limits.
Keep average and peak demand separate. Add replication, indexes, retries and safety headroom to raw arithmetic before selecting capacity. Load-test the busiest ownership key and recovery traffic as well as uniform happy-path throughput.
APIs and data model
- POST /communities/{id}/posts {body,parentId,requestKey} -> post
- PUT /posts/{id}/vote {value,version} -> current vote
- GET /threads/{id}?cursor=...; GET /communities/{id}/feed?cursor=...
post(id,community_id,author,parent_id,root_id,body_version,status,created_at)
vote(post_id,user_id,value,PRIMARY KEY(post_id,user_id))
feed_projection(community_id,rank_version,post_id,score); moderation(post_id,policy_version,state)Authorize resource ownership at the API boundary; do not trust IDs or state supplied by a client. Bind retry identity to the caller and payload for mutating operations. Reject an incompatible replay instead of returning an unrelated stored result.
Component relationships
Read the diagram
Follow the labeled relationship panels; they are separate directed paths, not one global timeline.
Step-by-step design
1. Establish the authority
Persist posts and parent/root relationships with bounded body size and community permissions. Page replies by a stable key instead of returning an unbounded recursive tree. A tombstoned parent can preserve reply structure while hiding removed content.
2. Make retries and concurrent work safe
Keep one authoritative vote per user/post and project aggregate scores asynchronously. Ranking combines a stated age/engagement policy; pin a ranking snapshot or use stable pagination semantics so score changes do not cause uncontrolled repeats.
3. Scale and recover the critical path
Fan out feed candidates with per-community quotas and hot-thread isolation. Enforce current moderation status when serving, including cached candidates. Search and notification indexes consume outbox events with independent replay checkpoints.
Worked request and concurrency example
User U upvotes P, retries after a timeout and later switches to a downvote. The unique vote row prevents duplicate votes; a versioned update changes the value once and emits a new projection event. A reader paginating a popular thread uses (created_at,id) cursors for replies. If moderators remove P, the body is replaced by a tombstone while allowed child replies remain addressable, and feed serving filters it even before cached scores refresh.
Failure and recovery walkthrough
A moderation event is delayed in one projection. Recheck authoritative removal/version at serving for sensitive content; invalidating only one cache does not cover search, feeds and notifications. A single giant thread needs time-bucketed replies and bounded fanout.
Read the diagram
This numbered trace follows one scenario; explain the durable evidence at each transition.
Decisions and alternatives
| Decision | Trade-off |
|---|---|
| Alternative 1 | A chronological reply order gives stable pagination; ranked replies improve relevance while needing snapshot/version policy. |
| Alternative 2 | Sharded approximate score counters reduce contention but lag. The final per-user vote record remains the authority for vote changes and rebuilds. |
Operational contract
Monitor per-community/thread load, score projection lag, moderation propagation and spam rejection. Test duplicate votes, removed parents, cursor stability and an abusive hot thread without starving other communities.
Choose alert thresholds from the agreed user-facing objective. Assign an owner for stuck work and a replay/repair procedure that preserves the original business identity. Bound queue depth, concurrency and recovery throughput so an outage does not produce an uncontrolled catch-up burst.
Foundation, senior and staff depth
- Foundation: explain the user action, model, first complete request and the correctness constraint without relying on a list of technologies.
- Senior: defend this lesson's partition/coordination boundary, capacity estimate and failure recovery; explain the cost of the rejected alternative.
- Staff: identify failure domains and operational ownership, stage a rollout with measured guardrails, and state when rollback stops being safe.
Practice before revealing the answer
Spend 45 minutes: 5 clarifying scope, 7 on capacity/APIs/state, 12 on the first architecture, 15 on the concurrency and failure examples, and 6 on trade-offs and operations. Draw your own design before comparing it with this chapter.
Question: How do you stop a popular thread from making every reply read scan the whole tree?
Show answer and explanation
Answer: Store root and parent IDs explicitly, index the requested root/parent plus pagination key and cap page size/depth. Fetch additional subtrees on demand and isolate extreme hot roots.
Verification and rollout
Reproduce the worked example using two concurrent actors or a repeated request where applicable. Inject the stated failure between the durable transition and its acknowledgment; verify the resulting state and user-visible outcome. For read/ML paths, test missing or stale dependencies and verify the documented fallback still enforces permissions. Use a small canary, compare correctness and user-facing latency with the baseline, and roll back when those guardrails regress. Do not use an average throughput number as evidence that a tail-latency target is met.
Primary technical reference
Official documentation for the mechanism used in this exercise. This lesson is an original interview design, not a description of undisclosed company internals.
Related study
Before this design, review these mechanisms and identify which owns the critical state transition:
Use the Interview Playbook to adapt the depth and timing, then return to the question breakdown overview.