Voting and ranking algorithms
How Reddit, Hacker News and review sites rank content: raw scores and their problems, time decay and hot ranking, the Wilson score lower bound for ratings, Bayesian averages for star ratings, controversy scores, vote manipulation defences, and computing rankings efficiently at scale.
Reading is half of it. See this used in a real interview: walk through Design Reddit →
"Sort by hot", "best comments first" and "top rated restaurants" all need a score that turns votes or ratings into a ranking. Naive scores fail in predictable ways: old posts dominate forever, an item with one five-star review beats one with a thousand 4.8s. The fixes are well known formulas worth having in your head for Reddit, news feed and review-site questions, along with how to compute them at scale.
Why raw scores fail
- Upvotes minus downvotes: old content accumulates votes and stays on top; new content never surfaces.
- Average rating: tiny samples dominate; one 5-star review ranks above 4.9 from 2,000 reviews.
- Percentage positive: 1 of 1 (100 %) beats 950 of 1,000 (95 %).
Time decay: "hot"
To keep front pages fresh, scores decay with age. Two well-known forms:
Hacker News style (gravity):
score = (votes − 1) / (age_in_hours + 2) ^ 1.8The exponent (gravity) controls how fast items sink.
Reddit's classic hot formula:
order = log10(max(|ups − downs|, 1))
sign = 1 if ups > downs, −1 if fewer, 0 otherwise
hot = sign × order + seconds_since_epoch / 45000The logarithm means the first 10 votes count as much as the next 90; the time term means a post needs about 10 times the votes to rank level with one posted 12.5 hours later. Because the time term only grows, scores never need recomputing as time passes: new posts simply start higher. That makes it cheap to store and index.
Confidence: Wilson score
For "best" comments or up/down ratings, rank by the lower bound of the Wilson score confidence interval for the true positive fraction:
p̂ = positive / n, z ≈ 1.96 for 95 %
lower = (p̂ + z²/2n − z·sqrt(p̂(1−p̂)/n + z²/4n²)) / (1 + z²/n)Items with few votes get a conservative score; as votes accumulate, the score approaches the true ratio. 9 of 10 positive ranks below 95 of 100. Reddit's "best" sort uses this idea.
Bayesian averages for star ratings
For 1 to 5 star ratings, blend each item's average with a prior:
score = (C × m + sum_of_ratings) / (C + n)where m is the global (or category) average rating and C is a confidence weight (like a typical number of reviews). A new restaurant starts near the global average and moves toward its own as reviews arrive. Useful for review sites and marketplaces. See Design Yelp.
Controversy
"Controversial" ranks items with many votes split evenly: for example, (ups + downs) raised to a power that shrinks as the split becomes lopsided. Only items with substantial engagement qualify.
Personal and quality signals
Modern feeds start from these scores but add personalisation, author reputation, freshness and quality models. See recommendation systems and search ranking and relevance.
Vote manipulation
Ranking invites gaming: vote rings, bots, purchased upvotes. Defences:
- Count votes from new or low-reputation accounts with less weight, or not at all.
- Detect coordinated voting (same IPs, devices, timing patterns) and discount it.
- Hide exact vote counts briefly ("vote fuzzing") so manipulators cannot see their effect.
- Rate-limit voting per account.
See trust and safety.
Computing rankings at scale
- Votes are recorded per (user, item) for idempotency and undo, and counted asynchronously. See counting at scale.
- Scores are recomputed when counts change, batched over short windows for hot items.
- Ranked lists per community and sort are kept in sorted sets or precomputed lists for the first few pages, refreshed every few seconds or minutes, and served from cache. See skip lists and sorted sets.
- Time-independent formulas (like Reddit's hot) allow storing a static score in an index; gravity-style formulas need periodic recomputation for the candidate set (recent items only, since old ones cannot rank).
- Deep pages are rarely viewed; compute them on demand.
In the interview
"Votes are stored per user and item, aggregated asynchronously; each post's hot score is log10 of net votes plus a time term, so it never needs recomputing; each subreddit's first pages of hot posts live in a sorted set refreshed from score updates; comments sort by Wilson lower bound; votes from new accounts are discounted." See Design Reddit and comments and threads.
Checklist
- Avoid raw averages and raw net votes for ranking.
- Time decay (gravity or log-plus-time) for "hot".
- Wilson lower bound for up/down "best".
- Bayesian average for star ratings.
- Manipulation defences: reputation weighting, ring detection, fuzzing, rate limits.
- Asynchronous counts, batched score updates, cached ranked lists.