Like a shopkeeper who has memorised the ten most popular things people ask for, for every first few letters. You say "ma" and they instantly suggest "mangoes, masala, matches". No searching at the counter; the answers were prepared in advance.
Design search autocomplete (typeahead): as a user types into a search box, show the top 5–10 suggested completions for the current prefix, ranked by popularity, updating on every keystroke. Think Google's search suggestions or an e-commerce search bar.
GET /v1/suggest?q=how%20to%20ma&limit=10&locale=en-IN
-> 200 { "suggestions": ["how to make tea", "how to make money online", ...] }
Cache-Control: public, max-age=300
SERVING (read path, hot)
browser (debounce ~100 ms, local cache of prefixes)
-> CDN / edge cache (popular prefixes)
-> Suggest service (in-memory trie or prefix->topK map, replicated)
BUILDING (offline / near-real-time)
search queries -> log -> [ queue ] -> aggregation (e.g. hourly counts, decayed)
-> build job: compute top-K per prefix -> new index snapshot
-> distribute snapshot to suggest servers (swap atomically)
trending path: streaming counts over the last minutes -> small "trending" overlay
(root)
|
h
|
o top: [how to make tea, how are you, hotel near me ...]
|
w top: [how to make tea, how are you, how to lose weight ...]
...
Naive lookup: walk to the prefix node, then DFS the whole subtree and sort
-> too slow for short prefixes ("a" has millions of completions)
Optimised: store the top K completions at EVERY node during the build
-> lookup = walk len(prefix) nodes + return a precomputed list
O(prefix length), independent of subtree size
Memory is the cost: every node stores K references. Limit prefix depth (e.g. 20 characters), drop queries below a frequency threshold, and shard the trie by first characters if it doesn't fit on one machine. An equivalent simpler structure is a key-value map prefix → [top K] for all prefixes of all popular queries, stored in Redis or a fast KV store.
score(q) = sum over time buckets: count_in_bucket * decay^(age_in_buckets)
e.g. decay 0.9 per day -> last week's burst fades, steady queries persist
Rebuild the main index every few hours from aggregated counts;
overlay "trending now" from a streaming top-K (count-min sketch + heap) per region.