skip to content

questions

22

In a search-box autocomplete service, why does one-request-per-keystroke traffic push designs toward precomputed suggestion lists instead of ranking at request time?

level: juniorimportance: must knowfreq 62%

answer

  1. count requests per typed query
  2. the next keystroke is a deadline
  3. rank offline, look up online
  4. prefix maps to a short list
  5. short prefixes are shared

basics

~20 s

Each keystroke can send a request, so autocomplete sees several times the traffic of full search and must answer before the next key. Precomputing ranked suggestions per prefix turns each request into a cheap lookup.

solid answer

~50 s

A user typing an eight-character query can send a suggestion request on most of those keystrokes, so the autocomplete endpoint takes **several times** the request rate of the search endpoint itself. Each response is also only useful if it arrives before the next keystroke, which leaves a budget of roughly `100 ms` end to end. Ranking candidates at request time (scanning matches, scoring them, sorting) is too expensive at that rate and latency. So the work moves offline: a batch job reads query logs, scores candidate completions, and stores a short, already-ranked **top-k list per prefix**. Serving then becomes a bounded lookup of `prefix -> list`, and because short prefixes are shared by many users, those lists are also highly cacheable. The price is freshness and flexibility, which a trending overlay and a small request-time rerank can partly buy back.

go deeper

for a junior

Recall that each keystroke can be a request and that the answer must arrive before the next key. Then state the fix: rank offline, store a top-k list per prefix, look it up at request time.

for a middle

Explain why request-time ranking is worst for the shortest prefixes, since they match the most candidates and are requested most often, and how a precomputed list makes cost depend on prefix length and k instead.

for a senior

Show you can estimate the traffic multiplier with stated assumptions, and name what precomputation costs in production: stale suggestions, weak personalization, and memory growth with k.

for a principal

Frame precomputation as moving cost from the hot path to a build pipeline, and discuss how much request-time reranking to allow before the latency and cacheability benefits erode.

## What an autocomplete service serves **Autocomplete** (also called **typeahead**) is the dropdown of suggested queries that appears under a search box while the user types. Each suggestion is a whole query the system believes the user probably means, such as `running shoes` for the typed text `run`. The typed text is the **prefix**; the suggestions are **completions** of it. The server side of this feature has an unusual shape compared with ordinary search: - the input is tiny (a few characters), - the output is tiny (usually 5-10 strings), - but the request rate is very high and the latency budget is very tight. ## Why the load is extreme Full search runs once per submitted query. Autocomplete can run once per **keystroke**. An illustrative estimate, with the assumptions stated: 1. Assume a site peaks at **5,000 submitted searches per second**. 2. Assume the average query is 8 characters long, and the client, after its own throttling, sends a suggestion request on about **5** of those keystrokes. 3. Suggestion traffic is then about 5,000 x 5 = **25,000 requests per second** - five times the search load, for a feature that returns ten short strings. On top of the rate, each answer has a deadline. If the suggestions for `ru` arrive after the user has already typed `run`, they are useless. Interactive-feel guidance puts that budget near **100 ms** end to end, and the network round trip consumes a large part of it before the server even starts work. ## Precompute instead of compute There are two broad ways to produce the list for a prefix: | Approach | Work per request | Freshness | Flexibility | |---|---|---|---| | **Rank at request time** | find all matching candidates, score each, sort, cut to k | immediate | high: filters, personalization, any scoring | | **Precomputed top-k per prefix** | one lookup of an already-sorted short list | as fresh as the last build or refresh | lower: ranking fixed at build time | Ranking at request time means the cost grows with the number of candidates under the prefix. A one-letter prefix can match millions of past queries, so the shortest prefixes - which are also the most frequently requested - would be the most expensive. That is the worst possible combination. Precomputation flips it. An offline **batch job** reads the query logs, counts how often each query was issued (often with a time decay so old popularity fades), and for every prefix stores the best **k** completions in order. At serving time the work is: 1. locate the entry for the prefix (a walk down a **trie**, or a key lookup in a prefix-to-list map); 2. return the stored list, optionally after a light filter or rerank over those few items. The cost now depends on the prefix length and on k, not on how many queries share the prefix. ## Side benefits of precomputation - **Cacheability.** The set of short prefixes is small (26 + 676 + 17,576 = 18,278 strings of one to three lowercase Latin letters), and most typed queries pass through them, so their lists can be cached close to users. - **Predictable latency.** Every request does roughly the same amount of work, which keeps tail latency flat. - **Offline quality control.** Unsafe or low-quality suggestions can be removed during the build, before anyone sees them. ## What precomputing gives up Precomputation is a trade, not a free win: - **Freshness.** A term that becomes popular this morning is missing until the next build, which is why production designs add a **trending refresh** path. - **Personalization and filters.** A single global list per prefix cannot reflect one user's history or a selected category. A common compromise is to precompute a slightly longer list (say 20 items when 8 are shown) and rerank or filter those few at request time. - **Storage.** Every stored prefix carries its own list, so memory grows with the number of prefixes times k. ## Summary Per-keystroke traffic multiplies the request rate, and the next keystroke sets a hard deadline. Moving the ranking offline and serving a stored top-k list per prefix makes each request cheap and uniform, at the cost of freshness and flexibility that the rest of the design then has to recover.

  • What does a precomputed suggestion list give up compared with ranking at request time?
    Freshness, because new terms appear only after the next build or a trending refresh; flexibility, because one global list per prefix cannot reflect a user's history or an active filter; and memory, because each prefix stores its own list. Designs recover some of this by storing a slightly longer list and reranking those few items per request, plus a small overlay for trending terms.
  • Why store more suggestions per prefix than the dropdown shows?
    Request-time steps such as removing a suggestion that is blocked for a region, or reranking by a user signal, discard or reorder items. If exactly the displayed number were stored, any removal would leave the dropdown short. Storing, for example, 20 for an 8-item dropdown leaves headroom, and memory grows only linearly with that k.

A coffee shop that pre-brews its three best-selling drinks before the morning rush can hand them over instantly, while made-to-order drinks would stall the queue. The trade-off is that a drink nobody expected is not ready.

saying these in an interview costs you the question

  • Autocomplete load equals search load, since it is one request per query.
  • Running the full search query on every keystroke is fine at scale.
  • Precomputing means storing every string a user could possibly type.
  • Short prefixes are cheap to rank at request time because they are short.
  • Precomputed suggestions cannot be refreshed until a full daily rebuild.
open as a page

For a product catalog's search index, what is the difference between a batch rebuild and near-real-time incremental indexing?

level: juniorimportance: must knowfreq 60%

basics

~20 s

A batch rebuild periodically re-reads the whole catalog and builds a fresh index, so results lag by up to the rebuild interval. Near-real-time indexing applies each change as it commits, giving seconds of lag but needing an always-running pipeline.

open as a page

In a search engine whose index is split across many shards, how does scatter-gather serve a query and return the global top 10?

level: juniorimportance: must knowfreq 60%

basics

~10 s

A coordinator sends the query to every shard in parallel. Each shard scores its own documents and returns only its local top 10. The coordinator merges those lists and keeps the best 10 overall.

open as a page

In a web crawler, what job does the URL frontier do beyond holding a list of URLs to fetch?

level: juniorimportance: must knowfreq 60%

basics

~20 s

The URL frontier holds every discovered but unfetched URL and decides what to fetch next and when: it orders URLs by priority and spaces out requests to each host, so the crawler stays polite and spends its budget on valuable pages.

open as a page

For server-side typeahead, how does a trie with precomputed top-k per node compare with an edge-ngram index and an FST?

level: middleimportance: must knowfreq 55%

basics

~20 s

A top-k trie gives lookups proportional to prefix length but costs memory; an edge-ngram index reuses search infrastructure and ranks at query time, costing index size and latency; an FST is compact and fast but immutable, rebuilt offline.

open as a page

Why do dual writes from application code to both a product database and its search index drift out of sync?

level: middleimportance: must knowfreq 64%

basics

~20 s

The two writes share no transaction: a crash or timeout between them leaves one side stale, and concurrent writers can reach the index out of order. Deriving index updates from committed database changes, through an outbox or change capture, closes the gap.

open as a page

When a web crawler's URL frontier uses priority front queues and per-host back queues, how does it stay polite without losing prioritisation?

level: middleimportance: must knowfreq 55%

basics

~20 s

Priority front queues feed back queues that each hold one host, pulled with a bias toward high priority. A heap keyed by each host's next allowed fetch time picks the host to serve, so no host is hit concurrently or too soon.

open as a page

In a search cluster that fans each query out to 100 shards, how do hedged requests tame tail latency caused by rare per-shard slowness?

level: seniorimportance: must knowfreq 55%

basics

~20 s

If each shard is slow 1% of the time, a query that waits on 100 shards is slow about 63% of the time. A hedged request sends a backup copy to another replica once the first is late and uses whichever reply arrives first.

open as a page

In a typeahead service with a sub-100 ms budget, why does caching results for short prefixes pay off so well?

level: middleimportance: should knowfreq 48%

basics

~20 s

Short prefixes are few, most typed queries pass through them, and their suggestion lists change slowly, so a small cache near users gets a high hit rate and removes both server work and much of the network round trip.

open as a page

In a search-indexing pipeline consuming product change events, how do you stop a stale event from overwriting a newer document?

level: middleimportance: should knowfreq 46%

basics

~20 s

Give every event a monotonically increasing version from the source of truth, such as a row version or commit-log position, and write to the index only if that version is newer than the stored one. Partitioning events by product ID keeps each product's changes in order.

open as a page

In a search engine sharded across 50 index shards, why does jumping to results page 1,000 cost far more than page 1?

level: middleimportance: should knowfreq 45%

basics

~20 s

Any shard could supply results 9,991-10,000, so each shard must return its own top 10,000, and the coordinator merges 500,000 entries to keep 10. Cursor paging avoids this by resuming after the last hit's sort key.

open as a page

In a web crawler handling billions of URLs, how do URL normalisation and a seen-URL set keep it from fetching the same URL twice?

level: middleimportance: should knowfreq 50%

basics

~20 s

Normalisation rewrites each URL into one canonical spelling (lowercase scheme and host, no default port or fragment, resolved dot segments, no session parameters); the crawler then checks a fingerprint of that form against a seen-URL set before admitting it to the frontier.

open as a page

How would you define and measure an index-lag SLO for a product-search index fed from a transactional database?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Define lag as the time from a change committing in the database to it appearing in search results, and target a percentile, such as 99% of changes within 30 seconds. Measure it with commit timestamps carried through the pipeline plus synthetic canary products.

open as a page

When a product-search index is fully rebuilt into a shadow index, how do you keep the writes that arrive during the rebuild?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Record the change stream's position before the bulk load starts, load a snapshot into the shadow index, then replay every change from that position with version-guarded writes until it catches up. Only then switch the alias; keep the old index for rollback.

open as a page

How does a web crawler detect near-duplicate pages that an exact content hash misses?

level: seniorimportance: should knowfreq 40%

basics

~20 s

An exact hash such as SHA-256 changes completely when one byte changes, like a timestamp or an ad. SimHash or MinHash fingerprints stay close for similar pages, so near-duplicates show up as a small Hamming distance or a high estimated Jaccard similarity.

open as a page

How would a web crawler detect and contain a spider trap, such as a calendar page whose next-month links never end?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Assume no host deserves unlimited pages: cap each host's page budget and each URL's length and depth, flag repeating path segments and session-ID parameters, and watch for hosts whose many URLs share content fingerprints. Suspect hosts get lower priority or are cut off.

open as a page

When a typeahead suggestion structure outgrows one machine, how do you choose between hash-sharding a prefix-to-list map and range-sharding a trie by prefix?

level: principalimportance: should knowfreq 30%

basics

~20 s

Hash-sharding a flattened prefix-to-list map spreads load evenly and routes each lookup to one shard but blocks traversal features like fuzzy matching; range-sharding a trie keeps traversal but needs load-based split points and special handling for short prefixes.

open as a page

For an interactive search box served by scatter-gather over many shards, how would you decide whether to return partial results when some shards miss the deadline?

level: principalimportance: should knowfreq 35%

basics

~20 s

Return partial results only if the missing shards hold little of the likely answer and the consumer can tolerate gaps. Flag the response as partial, keep it out of the result cache, and fail instead where completeness is the requirement.

open as a page

When partitioning a search index across machines, how does a document-partitioned layout differ from a term-partitioned one?

level: middleimportance: nice to knowfreq 30%

basics

~20 s

A document-partitioned index gives each shard a complete index over some of the documents, so every query hits every shard. A term-partitioned index gives each shard whole postings lists for some of the terms, so a query hits only its terms' shards.

open as a page

In a search-box typeahead, how can suggestions tolerate a typo in the typed prefix without breaking the latency budget?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

Allow a small, length-dependent edit distance, walk the suggestion structure with an automaton that prunes branches exceeding it, rank exact matches above fuzzy ones, and cap the work, often using fuzzy matching only when exact results are too few.

open as a page

With a fixed daily fetch budget, how should a web crawler decide how often to recrawl each page it already knows?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

Estimate each page's change rate from past fetches and weight it by importance, then spend the budget where a revisit most improves freshness. Revisiting strictly in proportion to change rate can backfire on pages that change faster than you can return.

open as a page