ayushsalampuriya.xyz Revise

System Design · Design Question

Design Autocomplete

Typeahead suggestions: tries, ranking by popularity, low-latency serving, and personalization at the edge.

In simple words: Map each typed prefix to a short ranked list in memory. Build popularity data offline so the live lookup stays fast.

Concrete example: Typing uni in Google may suggest "university", "unicode", and "unicorn" within ~50 ms because a trie stores top queries for each prefix, ranked by search logs.

1. Requirements

Functional

Non-functional

Back-of-envelope

100M users × 20 search sessions × 10 keystrokes ≈ 20B raw key events/day. Client debounce and a 2-character minimum can cut origin traffic by several times; size for ~100k peak QPS.
Prefix "uni" → university, unicode, unicorn, ... Update popularity from search logs daily / nearline

2. API

GET /v1/suggest?q=uni&limit=10&lang=en → { "suggestions": [ { "text": "university", "score": 0.91 }, { "text": "unicode", "score": 0.88 } ] }

3. Data structures

Trie (prefix tree)

root / \ u ... | n | i → topK: [university, unicode, ...]

Each node can cache top-K completions for its prefix so serving does not walk the whole subtree. Memory-heavy at web scale — shard or use succinct structures / analytics DB.

Alternatives

4. Ranking

score = f( frequency, recency, click-through, personal history ) Offline job aggregates query logs → popularity table Personal: boost queries user issued before (small Redis profile)

5. High-level design

Client (debounce 30–50ms) → Edge / API → Suggest Service | in-memory trie shard OR Redis | Build pipeline: Search logs → aggregate → publish new trie snapshot → reload workers

6. Deep dive — serving latency

7. Data model

query_stats(query, freq, last_seen) -- analytics store trie_snapshots(version, blob_or_path) -- published artifacts user_recent_queries(user_id, queries[]) -- personalization cache

8. Scaling

9. Edge cases

10. Offline vs online split

Offline (daily/hourly): logs → aggregate counts → build trie snapshot → publish to object store Online: suggest servers mmap/load snapshot optional delta stream for viral queries personalization re-rank using small user profile

Keep online path CPU-light: dictionary lookup + tiny re-rank. Heavy ML belongs in offline candidate generation when possible.

11. Multilingual notes

12. Failure modes

Interview talking points

  • Lead with: Keep serving in memory and move heavy ranking work offline.
  • Prefix → top K; trie with cached top-K per node is the classic model.
  • Popularity from search logs; rebuild snapshots offline.
  • Serve from RAM; debounce client; cache hot prefixes.
  • Personalization is a light re-rank on top of global results.
  • Shard tries; atomic snapshot reload.
  • Min prefix length + rate limits control cost.
  • Filter unsafe suggestions in the pipeline.