How Reddit Stores Comment Trees and Ranks Hot Posts
The Core Problem
A comment thread is a tree. Each comment can reply to any other, so depth is unbounded. If you store only "this comment's parent id" and then try to load a whole thread, you walk the tree one level at a time, one query per level, which gets slow for deep or wide threads. Loading a popular post with thousands of nested comments should not take thousands of queries.
Ranking is the second problem. If the front page sorted by raw vote count, the highest-voted post of all time would sit at the top forever. If it sorted by newest, quality would drown in noise. You need a score that blends how good a post is with how fresh it is, so good new posts can climb and old ones fade even if they were once popular.
Key Design Decisions
Store the parent pointer, but do not traverse at read time. The simple model is a parent_id per comment, which is easy to write but expensive to read as a tree. To load a thread cheaply, fetch all comments for the post in one query, then assemble the tree in application memory. One read, in-memory tree building. This works because a single post's comments, while numerous, fit in memory to assemble.
Consider a path or closure model for deep trees. For very deep threads, some systems store a materialized path on each comment - an encoded ancestor chain - so you can fetch an entire subtree with a single prefix query and sort by the path to get correct display order. Another option is a closure table that records every ancestor-descendant pair, which makes subtree queries direct at the cost of extra write work. The right choice depends on how deep threads get and how often you read subtrees versus write comments.
Cache the assembled thread. A hot thread is read far more than it is written, so caching the assembled comment tree and updating it as new comments arrive avoids rebuilding it on every view.
Rank with a time-decaying score. The hot ranking blends a post's vote balance with its age. The core idea is that the logarithm of the score contributes a lot for the first votes and less for each additional vote, while a steady time term pushes older posts down. A post submitted later starts with a built-in advantage, so a strong new post can overtake an older one without needing an impossible number of votes. Because the score depends on submission time and votes, it can be computed and stored per post and only recomputed when votes change.
The Trade-offs
- The parent-pointer plus in-memory assembly model is simple and cheap to write, and it is fine for most threads, but pathological threads that are extremely deep or wide stress the single fetch.
- Materialized paths make subtree reads fast but add cost and complexity on every insert and move, and moving a comment means rewriting paths.
- Closure tables make ancestor queries trivial but multiply write volume, since one comment at depth
nwritesnancestry rows. You are trading read speed against write cost, and the correct point depends on your read-to-write ratio. - Hot ranking trades precision for stability and cheapness. A decay-based score can be precomputed and rarely needs recalculation, which keeps the front page cheap to serve, but it is a heuristic, not a truth, and it can be gamed by early vote bursts. Tightening it against manipulation means adding signals beyond votes and time, which complicates the clean formula.
How the Real System Does It
The real design stores comments with parent references, loads a post's comments in bulk and builds the tree in memory or uses a path model for deep subtrees, and caches hot threads heavily. Front-page ranking uses a score that combines vote balance with a time term so freshness and quality both matter, computed per post and refreshed on vote changes rather than on every page view.
The lesson that carries over: model the read you actually perform. Comments are written once but read constantly, so pay at write time or cache aggressively to make reads cheap, and let ranking be a stored score, not a query you run on every request.
I wrote the full breakdown, with diagrams and the data model, here: https://www.systemdesign.academy/interview/design-reddit
Comments
No comments yet. Start the discussion.