Design a Comments Thread
System design for nested comments: replies, pagination, real-time updates, and moderation. Frontend architecture and data shape.
Comments threads appear on content sites, dashboards, and collaboration tools. They can be flat or nested, with pagination and sometimes real-time updates. Here's how to approach this in a system design interview and what trade-offs to discuss.
Requirements Clarification
Functional: Display comments in a thread (flat or nested); post a comment; reply to a comment; edit/delete (own comments); optional: reactions, sort (newest/oldest/top). Non-functional: Load initial comments quickly; expand or paginate; real-time for new comments optional; handle deep nesting (e.g. max depth or "Load more replies").
Clarify: Is nesting unlimited or capped (e.g. one level of replies vs. full tree)? Do we need real-time for new comments or is polling/refresh enough? Who can edit/delete—only author or also moderators? Answers will drive the data model and API shape.
Data Model and API
Comment: id, author, body, createdAt, parentId (null for top-level), replyCount. Tree can be built client-side from flat list with parentId, or API returns nested structure. GET /comments?postId=...&limit=...&cursor=... for initial load; GET /comments/:id/replies for "Load more replies"; POST to create; PATCH/DELETE for edit/delete.
Flat vs nested API: A flat list with parentId is easier to paginate (e.g. "next 20 top-level comments") and to update (one comment object). A nested response is easier to render without client-side tree building but can be heavy for deep threads. Many systems use flat in the API and build the tree on the client; the frontend can then lazy-load reply pages and merge them into the tree. Include replyCount so the UI can show "3 replies" before loading them.
Frontend Component Structure
CommentThread (container), CommentCard (single comment: author, body, actions, reply form when "Reply" clicked), recursive CommentCard for replies. For deep threads, either cap depth and show "View N more replies" or flatten with indentation. Virtualize only if thread is extremely long.
State management: Keep loaded comments in a normalized structure (e.g. map by id, with parentId for tree shape) or as a tree. When the user posts a new comment, add it optimistically to the tree and then confirm with the server response (replace temp id with real id). For edit/delete, update local state and call the API; on failure, revert and show an error. Use React Query or similar to cache and invalidate so that navigating away and back doesn't refetch unnecessarily.
Pagination and "Load More"
Initial load: top-level comments only, page size (e.g. 10). "Load more" fetches next page and appends. Replies: load on demand when user expands "N replies" to avoid huge payloads. Cache loaded comments in client state (e.g. React Query) keyed by postId and optionally commentId for replies.
Cursor vs offset: For comments, cursor-based pagination (e.g. "after this timestamp or id") is usually better than offset so that new comments don't shift the window. When the user clicks "Load more replies," send the parent comment id and a cursor; the API returns the next page of children. Merge into the tree so the UI updates without a full refetch.
Real-Time Updates
Optional: subscribe to new comments for the post (WebSocket or SSE). When a new comment arrives, prepend or append to list and optionally show a "New comment" indicator. Optimistic updates: add the new comment to UI immediately, then confirm or rollback on server response.
Handling conflicts: If the user is typing a comment and a real-time event adds the same comment (e.g. from another tab), dedupe by temporary id or by matching author + body + timestamp. For edits and deletes from other users, apply the update to the local tree so the UI stays in sync. Consider debouncing or batching real-time updates so rapid activity doesn't cause excessive re-renders.
Moderation and Accessibility
If moderation is required, show "Pending" or "Hidden" state; only moderators see flagged content. Comments should be keyboard navigable and screen-reader friendly; use semantic list and aria-live for new comments if real-time.
Accessibility details: Use a list structure (ul/ol) for the thread and list items for each comment. For "Load more replies," ensure focus moves to the newly loaded content or that the button remains focusable. When a new comment appears via real-time, use aria-live="polite" so screen readers announce it without interrupting. Provide skip links or headings so users can jump to the comment form or to the start of the thread.
A comments thread design that separates top-level and reply loading, uses a clear data shape, and optionally adds real-time and moderation will demonstrate solid frontend system design. Keep the API contract stable so mobile and web clients can share the same backend.
Testing and Rollout
Test with deep threads (e.g. 5+ levels), many siblings, and rapid real-time updates to ensure the tree and virtualization behave correctly. Roll out reply pagination and real-time incrementally behind flags so you can measure performance and fix issues before they affect all users.
Related articles
- System DesignDesign a Real-Time Chat Application
System design for Slack/WhatsApp-style chat: WebSocket management, message ordering, offline support, typing indicators, read receipts, search, and file uploads.
Read article - System DesignDesign a Frontend Notification System
System design for toasts, badges, and notification center: queue management, auto-dismiss, priority, read/unread, real-time delivery (SSE/WebSocket), filtering, push notifications, and overflow behavior.
Read article - System DesignDesign a Search Results Page
System design for a search results page: filters, sorting, facets, infinite scroll vs pagination, and performance at scale.
Read article - System DesignDesign Autocomplete / Typeahead Search
System design for building a Google-like autocomplete search component: debouncing, caching, keyboard navigation, race conditions, and mobile considerations.
Read article