System Design blueprint · E-Commerce
Search autocomplete (typeahead)
Suggestions on every keystroke, served from a prefix trie rebuilt from real searches.
- Steps
- 6
- Subjective questions
- 32
- Objective questions
- 32
The problem and the outcome
Problem: Shoppers abandon search when suggestions lag or miss what everyone is buying.
Outcome: Relevant suggestions in under 50 ms, refreshed with every day's trends.
Architecture
How it works, step by step
- Each keystroke sends the prefix, debounced by about 100 ms.
- Popular prefixes are answered straight from the edge cache.
- The suggest service reads a trie that keeps the top suggestions at every prefix node.
- Every search is logged together with its clicks and purchases.
- A batch job rebuilds the trie from fresh counts and swaps it in without downtime.
- Recent personal searches are blended in before the list returns.
Tech stack
- Trie or finite-state transducer in memory
- Elasticsearch / OpenSearch completion suggester
- Edge cache for hot prefixes
- Spark / batch jobs over query logs
Key design decisions
- Store the top-k completions at every trie node, so a lookup is a walk down the prefix with no search below it.
- Rebuild the trie offline from query logs (hourly or daily) and swap it in, keeping the request path read-only.
- Debounce keystrokes on the client and cache popular prefixes at the edge.
Common mistakes
- Computing top-k by searching the whole subtree on every keystroke.
- Updating the trie in place on the live path, causing lock contention.
- No filtering, so offensive or out-of-stock suggestions appear.
What to measure
- Suggestion p99 latency (under ~100 ms)
- Suggestion click-through rate
- Keystrokes saved per search
Most-asked interview questions
Subjective questions 32
1Design search autocomplete for a large e-commerce site.Asked almost every time
Aggregate query logs offline into counts per query, weighted toward recent and converting searches. Build a trie where each node stores its top-k completions, shard it by prefix, and serve it from memory behind an edge cache for short, hot prefixes. The client debounces input. Personal history and trending queries are blended in at request time.
2Walk through the architecture of a typeahead service.Asked almost every time
Clients send debounced prefix requests to a suggestion service that reads precomputed top-k suggestions from an in-memory trie or prefix map, sharded by prefix and replicated. Offline pipelines aggregate search logs to rebuild the index regularly, while a streaming path adds trending queries between rebuilds. Responses are cached at the CDN and in the browser.
3How do you rank suggestions?Asked almost every time
Combine query popularity (with time decay), recent trends, personal history, location and language, business signals such as product availability, and filters for unsafe or low-quality queries. Weights are tuned with click-through data and A/B tests.
4How do you keep latency under 100 ms?Asked almost every time
Precompute top-k per prefix so lookups are O(prefix length), keep the index in memory close to users, cache popular prefixes at the CDN, debounce on the client, cancel stale requests, and return small payloads.
5Why store top-k results at each trie node?Very often asked
Without it, each request must traverse the whole subtree under the prefix and sort, which is slow for short prefixes with millions of completions. Precomputing top-k makes every lookup proportional to the prefix length, at the cost of extra memory and a rebuild step.
6How do you handle typos and spelling mistakes?Very often asked
Add fuzzy matching with edit distance for short prefixes, keep a spell-correction dictionary from search logs (queries users corrected), and use phonetic or n-gram indexes; limit fuzziness for performance.
7How do you personalise suggestions?Very often asked
Blend global suggestions with the user's recent searches and inferred interests at query time, stored per user in a fast store, with privacy controls to clear history.
8How do you shard the suggestion index?Very often asked
Shard by prefix ranges (with care, since 's' is far bigger than 'x') or by hash of the first characters, rebalance using measured traffic, and replicate each shard for availability and read throughput.
9How do you filter offensive or unsafe suggestions?Very often asked
Maintain block lists, run classifiers on candidate queries during index builds, apply legal removals quickly through an override list checked at serving time, and monitor reports.
10How does the offline pipeline build the index?Very often asked
A batch job aggregates search logs over a window, normalises queries, counts frequencies with decay, applies filters, builds the trie with top-k lists per node, and ships the snapshot to servers that load it with a hot swap.
11How would you support multiple languages?Very often asked
Normalise text per language (case, accents, scripts), tokenise appropriately (CJK has no spaces), build separate indexes per locale and choose by user language, and support transliteration such as Hinglish to Hindi.
12How does autocomplete differ from full search?Very often asked
Autocomplete predicts queries from a prefix with tight latency budgets and small result sets, often from precomputed data. Full search retrieves and ranks documents for a complete query with richer relevance models.
13How would you design a trie node to return top suggestions quickly?Very often asked
Store at each node a small precomputed list of the top K completions beneath it with their scores, so a lookup walks to the prefix node and returns that list without exploring the subtree. Rebuild these lists offline when counts change.
14How do you combine global popularity with a user's context in ranking?Very often asked
Fetch top candidates by global score, then re-rank a short list with features such as the user's recent searches, location, language and time of day, using a lightweight model or weighted formula that runs in a few milliseconds.
15How do you show trending queries quickly, before the next rebuild?Often asked
Run a small real-time layer: count recent queries in a sliding window (a stream processor or Redis sorted sets) and merge those with the static trie results at request time.
16What client-side optimisations matter?Often asked
Debounce input (around 100–300 ms), cache results per prefix in memory, cancel in-flight requests when the user types more, prefetch on focus, and render keyboard-accessible listboxes.
17How do you evaluate autocomplete quality?Often asked
Measure suggestion click-through rate, keystrokes saved, mean reciprocal rank of the chosen suggestion, zero-suggestion rate and latency, and run A/B tests for ranking changes.
18How do you add trending queries quickly?Often asked
A streaming job counts queries in short windows, detects spikes compared with baselines, and pushes trending entries to a small fast-update layer merged with the main index at serving time.
19Why not query the database with LIKE 'prefix%' for every keystroke?Often asked
At scale, it is too slow and expensive under heavy keystroke traffic, cannot rank by popularity efficiently and hurts the primary database. A dedicated in-memory index is designed for this access pattern.
20How do you use Elasticsearch or OpenSearch for autocomplete?Often asked
Use completion suggesters (FST-based, very fast prefix lookup) or edge n-gram analysers with search-as-you-type fields, weighting suggestions by popularity; good for product catalogues of moderate size.
21How do you make autocomplete accessible?Often asked
Use the combobox pattern: an input with role="combobox", aria-expanded, aria-controls and aria-activedescendant, a listbox of options, arrow-key navigation, Enter to select and Escape to close.
22How do you handle a viral new query that has few historical counts?Often asked
The trending layer boosts it based on recent velocity rather than total count, with safety filters, so it appears within minutes rather than after the next batch rebuild.
23How large is a typical suggestion index?Often asked
If you keep 10 million popular queries averaging 25 bytes with top-k lists of IDs at each node, the index fits in tens of gigabytes, so it can live in memory on each replica.
24How do you autocomplete entities such as products or places rather than queries?Often asked
Index entity names, aliases and popular attributes, rank by entity popularity and availability, return rich results with type, image and ID, and navigate directly to the entity page when one is chosen instead of running a search.
25How do you handle autocomplete for very short prefixes like one character?Often asked
Serve precomputed results for all one- and two-character prefixes from cache or the edge, since they are few and very popular, and consider waiting for two characters before showing suggestions to reduce noise.
26How do you keep suggestions fresh without rebuilding the whole index?Often asked
Use a two-tier design: a large index rebuilt daily or hourly, plus a small real-time index fed by a stream of recent queries. Merge results from both at query time with a recency boost.
27How do you design autocomplete for a search box inside an app with permissions?Often asked
Only suggest items the user may see, by filtering on access lists in the index or per-tenant indices, never leak private titles through global popularity, and re-check access when the suggestion is opened.
28How do you protect autocomplete from abuse?Sometimes asked
Rate-limit per client, ignore bot traffic in log aggregation, require minimum distinct users before a query can be suggested, and filter manipulation attempts.
29How do you roll out a new index safely?Sometimes asked
Load the new snapshot on a canary, compare suggestions and latency with the old one, then hot-swap across the fleet with the ability to roll back instantly.
30What should the suggestion response contain?Sometimes asked
The suggestion text, a highlight range for the matched prefix, a type (query, product, category), optional thumbnail or metadata, and an ID for click logging.
31How is privacy handled in query logs?Sometimes asked
Strip or hash personal data, require a minimum number of users per query before suggesting it, keep retention limited, and let users clear personal history.
32How do you measure autocomplete latency from the user's point of view?Sometimes asked
Instrument the client to record time from keystroke to suggestions rendered, include network and rendering time, report p50 and p95 by region and device, and track abandoned responses that arrive after a newer keystroke.
Objective questions 32
1Which data structure is classic for prefix lookups?Asked almost every time
Why: A trie stores strings by shared prefixes, so all completions of a prefix are under one node.
2What makes prefix lookups fast in a typeahead?Asked almost every time
Why: Lookup cost depends on prefix length.
3What should rank suggestions besides popularity?Asked almost every time
Why: Many signals combined.
4How do trending queries appear before the next rebuild?Asked almost every time
Why: Merged at serving time.
5Why debounce keystrokes on the client?Very often asked
Why: Waiting briefly after typing cuts request volume a lot with no visible delay.
6Why shard by prefix carefully?Very often asked
Why: Some letters are far busier.
7Which Elasticsearch feature suits fast prefix suggestions?Very often asked
Why: FST-based and very fast.
8How should unsafe suggestions be removed quickly?Very often asked
Why: Legal removals cannot wait.
9Which metric shows suggestions are useful?Very often asked
Why: Pair these with latency metrics.
10What should the client do as the user keeps typing?Very often asked
Why: Only the latest prefix matters.
11Which ARIA pattern fits autocomplete?Very often asked
Why: Arrow keys move through options.
12Precomputed top-K lists at trie nodes make lookups…Very often asked
Why: The answer is stored at the prefix node.
13Personalised re-ranking is applied to…Very often asked
Why: A small list keeps re-ranking fast.
14Where does the trie's ranking data usually come from?Often asked
Why: Real searches, clicks and orders show which completions people actually want.
15Typo tolerance is usually based on…Often asked
Why: Limit fuzziness for speed.
16Why is LIKE 'prefix%' on the main database a bad idea?Often asked
Why: Use a dedicated index.
17What must normalisation handle across languages?Often asked
Why: Each language needs its own rules.
18How are new index snapshots deployed?Often asked
Why: Rollback stays instant.
19Why require several distinct users before suggesting a query?Often asked
Why: One user's query is not a trend.
20Which is a reasonable debounce delay?Often asked
Why: Balances speed and load.
21Personal history in suggestions should…Often asked
Why: Privacy controls matter.
22Autocomplete differs from full search by…Often asked
Why: Prefix prediction is lighter.
23Fresh queries reach suggestions quickly through…Often asked
Why: The two-tier design balances freshness and cost.
24One-character prefixes are best served from…Often asked
Why: There are few of them and they are very hot.
25Entity autocomplete should return…Often asked
Why: Picking an entity goes straight to it.
26In an app with permissions, suggestions must…Often asked
Why: Suggestions can leak private names.
27What should a suggestion response include for logging?Sometimes asked
Why: Clicks train ranking.
28Which method handles CJK text without spaces?Sometimes asked
Why: Scripts differ in word boundaries.
29A viral new query is boosted by…Sometimes asked
Why: This is how trending detection works.
30Bot traffic in logs should be…Sometimes asked
Why: Bot traffic skews popularity counts.
31Where can popular prefix responses be cached?Sometimes asked
Why: Short TTLs keep them fresh.
32Real autocomplete latency should be measured…Sometimes asked
Why: Users feel network and rendering time too.
Track your progress through every blueprint in your dashboard.
Start learning