#11 Heavy-Read Rankings
App Store Rankings
Rank millions of apps by downloads and ratings per country and category, and serve those lists to a huge read audience.
What is being asked
Design the "top charts" of an app store: top free, top paid and top grossing, per country and per category, refreshed periodically and read by everyone who opens the store.
Requirements
Functional
- Record downloads, purchases and ratings.
- Produce ranked lists per chart type, country and category.
- Detect and discount manipulation.
Non-functional
- Read-heavy by several orders of magnitude.
- Lists may be minutes to hours old.
- Reads must be fast worldwide.
Design
- Each download or purchase is appended to an event log.
- A job aggregates counts per app per time bucket, per country.
- A scoring step combines recent downloads with decay, so yesterday counts more than last month, and applies fraud adjustments.
- The chart builder writes complete ranked lists, one per chart, country and category, to a ranking store.
- Lists are served through a cache and CDN. A request is a key lookup; nothing is computed at read time.
Key decisions and trade-offs
- Precompute everything. With reads vastly outnumbering writes, the lists are built offline and served as static data. Freshness is traded for speed and cost.
- Time decay. A plain total favours old apps for ever. Exponential decay or a rolling window lets new apps rise.
- Fraud. Bursts of installs from few devices or addresses are discounted before ranking, otherwise charts can be bought.
- Number of lists. Charts × countries × categories is large but each list is small, so storing all of them is cheap.
Follow-up questions
- How would you make the chart update within a minute for a launch event?
- How do you page through a list that changes between requests?
- How would you personalise the list without losing the caching?
- What signals would you use to detect paid install farms?