30% offEnding soon
FSD-045Frontend system design Premium

Design a Threaded Comments System

Design a threaded comments interface with independent branch pagination, optimistic replies, stable anchors, versioned edits, moderation, and live recovery.

Advanced 64 min read

A threaded comments interface is a viewer-scoped projection over normalized comment records and independently paginated parent connections. Temporary replies, edits, moderation, and live events may change that projection, but every accepted receipt must still match the current operation, version, branch, and viewer scope.

A small thread can be rendered with a recursive component and one nested JSON response. That approach feels natural because the screen looks like a tree. It becomes fragile when a popular root has thousands of replies, several branches are open, new comments arrive live, an author edits text on another device, or a moderator removes a parent while its descendants remain visible.

The hard problem is not drawing indentation. It is keeping identity, order, authorization, and reading position correct while different branches advance independently.

Clarify the conversation product

Ask how deep replies may go, whether the interface shows every level or flattens after a limit, and how roots and replies are ordered. Define edited labels, deleted-parent tombstones, reactions, mentions, attachments, drafts, moderation reasons, blocked users, locked threads, live updates, offline retry, and deep links.

Clarify what a link means. Does it identify one durable comment, a place in one ranked view, or a comment plus its ancestor path? Can a viewer open a link to a reply whose parent is collapsed? What happens if an ancestor is hidden by policy? The answers shape the API more than the indentation style does.

Set budgets for initial roots, reply pages, expanded branches, maximum visual depth, mounted rows, time to reveal a deep link, anchor movement, stale edit conflicts, duplicate optimistic creates, and live sequence recovery. Without budgets, "support large discussions" is not a testable requirement.

The public interview prompt

Design a browser-based threaded comments system. It supports paginated roots, independently expandable reply branches, optimistic creation, editing and deletion, moderation, reactions, live updates, deep links, keyboard access, and restoration to a previous reading position.

Explain:

  • comment, parent edge, branch connection, cursor, operation, version, viewer projection, and live sequence identity;
  • normalized storage, per-parent pagination, ordering, deduplication, and branch invalidation;
  • optimistic reply grafting, retry, acknowledgement, ID remapping, and rollback;
  • stale edit conflicts, tombstones, moderation visibility, and authorized actions;
  • deep-link ancestor hydration, focus, disclosures, status messages, and scroll anchoring;
  • large-thread rendering, maximum visual depth, virtualization, measurement, and cache limits;
  • live gaps, offline recovery, deleted parents, locked threads, and degraded modes;
  • testing, observability, privacy, rollout, and an evolution path.

What the premium solution covers

The full solution begins with a normalized graph and a separate ordered connection for every parent. It follows one optimistic reply from temporary graft to canonical acknowledgement, defines monotonic version and live-event rules, and preserves a pinned reading anchor while branches load. It also covers deep links, moderation, accessibility, rendering budgets, failure recovery, security, measurement, and rollout. The teaching media uses a winding comment branch, cursor sockets, a physical anchor tape, viewer-specific policy masks, and a deterministic projection-budget lab.

Premium solution

Continue with the complete system design

Unlock the architecture, state machine, API contracts, original diagrams, positioning model, accessibility decisions, performance budgets, testing plan, rollout strategy, scoring rubric, and interview walkthrough.

  • Detailed, beginner-friendly explanation
  • Production failure modes and trade-offs
  • Mobile-friendly architecture diagrams
  • Senior and staff-level interview signals
Unlock Premium

Frequently asked questions

Should a threaded comments API return one deeply nested JSON tree?
Usually not. Normalize comment records by ID and page each parent's ordered child connection independently. A large nested response is hard to cache, update, authorize, and recover after partial failure.
How do optimistic replies avoid duplicates after a retry?
Give the create command a stable operation ID. Render a temporary comment keyed by that operation, and map it to the canonical server ID exactly once when an acknowledgement with the same operation ID arrives.
How can replies load without moving the reader's current comment?
Capture a stable anchor comment and its viewport offset before insertion, then compensate for measured height changes above it. Native scroll anchoring helps, but explicit restoration is still needed for controlled expansion and virtualization.
How should comment edits handle two writers?
Send the version that the editor started from with an If-Match precondition. If the server rejects a stale edit, keep the draft, show the newer canonical text, and let the author compare, copy, or retry deliberately.
Should hidden or moderated comment text be sent to every browser?
No. The service should project only the fields and actions authorized for the current viewer. A tombstone can preserve conversation shape without delivering restricted content.
Does a nested comment thread need ARIA tree semantics?
Not automatically. Comments are usually document content with headings, articles, links, and disclosure buttons. Use tree semantics only when the interaction truly behaves like a single-select hierarchical widget.