Skip to content

Typeahead and Autocomplete

intermediate · 30 min · Last reviewed 31 Oct 2026 · by TheLearningLoop Team

Key takeaways

  • Precompute the top suggestions for each prefix (for example in a trie), so a request is a lookup and not a search.
  • Debounce keystrokes and cache short prefixes, because every user keystroke is a potential request.
  • A precomputed index is only as fresh as its last rebuild. Choose the refresh interval to match how fast trends matter.

Why typeahead is a classic design question, and what it teaches

Typeahead (also called autocomplete) shows suggestions as a user types into a search box. Each keystroke can start a request, the answer must arrive before the next key, and the list must be useful: the most popular or relevant completions of what has been typed so far. It teaches prefix indexes, precomputation, caching and update pipelines.

It gives you two things interviewers always ask about:

  • Very low latency: suggestions must appear in a fraction of a second, or they arrive too late to help.
  • Scalability: every keystroke of every user is a request, so the read load is huge compared with the number of searches.

Requirements to confirm first:

  • Functional: return the top few completions for a prefix, ranked by popularity or personal relevance, optionally fix typos.
  • Non-functional: responses in tens of milliseconds, very high request rate, suggestions that follow trends within minutes or hours.

Skip the design, or simplify it, when:

  • The list is short (a few hundred items): filter it in the browser.
  • You do not need ranking: a simple prefix query on an indexed column is enough.

Try it

A user types "card" one letter at a time. Change how the index works, then change the typing and the data.

Typeahead and Autocomplete

Step 1 of 6 · Press Space to play, arrow keys to step

Search box is empty

Search boxemptySuggestion servicewalks a prefix treeIndex1,000,000 queries

Initial state. A user types the word "card" one letter at a time. Each request must return the best few suggestions fast.

tick:
0
requests:
0
entries examined:
0
sees trending term:
no

1 tick = one step of the simulation.

Things to try:

  • Run the Prefix tree with a request for every keystroke. Each request is cheap, but there are four of them.
  • Switch to Scan every stored query and see how much work one request is.
  • Choose A new trending query appears and compare which approach sees it.

What to watch (counters at the last step):

  • Prefix tree, a request for every keystroke: 4 requests, 10 entries examined (1 + 2 + 3 + 4 nodes visited).
  • Prefix tree, with debounce: 1 request, 4 entries examined.
  • Scan, with debounce: 1 request, 1,000,000 entries examined.
  • Scan, a request for every keystroke: 4 requests, 4,000,000 entries examined.
  • Trending query: only the scan shows it ("sees trending term" is yes). Note that this option also waits for a pause before sending, so it makes 1 request, not 4.
  • For the prefix tree, "entries examined" counts the nodes visited, which equals the prefix length.

Ways to build the suggestion index

ApproachHow it worksGood whenWeakness
Database LIKE 'prefix%'Query the table for rows starting with the prefixA small or medium dataset with an indexHard to rank: a short prefix such as "a" matches a huge number of rows that must all be read to find the top few
Trie (prefix tree) with top results at each nodeEach node on the path of a prefix stores its best completionsVery low latency, huge dataRebuilt periodically, memory heavy
Sorted set with range queriesKeep terms sorted and read the range that starts with the prefixSimple and fast in a key-value storeRanking needs extra work
Search engineEdge n-gram (every leading slice of a word, such as c, ca, car, is indexed) or suggester featuresYou already run oneMore to run, and slower than a precomputed list

Precompute vs compute on the fly

  • Compute on the fly (scan or query when asked) is always fresh, but its cost grows with data size and request rate.
  • Precompute the top results for each prefix ahead of time, so a request is a lookup. It is very fast, but only as fresh as the last build, and it uses more memory.

Most systems precompute, because reads far outnumber changes, and refresh the data every few minutes or hours from a log of searches.

How the stored top results get into each node: the build job counts every query, then for each prefix keeps only the best few (for example the top 5) by weighted count, and writes that short list on the node. A request therefore never has to look below the node it reaches. Updating counts in place would mean changing the lists on every ancestor node of every searched query, so most systems rebuild in batches and add a small index of very recent queries for freshness.

How a typeahead request works

  1. The client waits for a short pause in typing (debounce, often 100 to 200 ms) so it does not send every keystroke, and it cancels requests that are now out of date.
  2. The request reaches a suggestion service through a CDN (a network of edge servers close to users) or load balancer. Personalised answers differ for each user, so they are usually not shared through a CDN. Popular prefixes such as "a" or "wh" are answered from a cache.
  3. On a miss, the service looks up the prefix in the index (a trie or sorted set) and returns the stored top results.
  4. In the background, search queries are logged, aggregated into counts (with the most recent queries weighted more), and used to rebuild the index periodically.
  5. The new index is swapped in without downtime.

Components and what each one does

  • Client: debounces keystrokes, cancels out-of-date requests, ignores late answers, and draws the list.
  • Cache or CDN: answers common prefixes without touching the index. It does not rank anything.
  • Suggestion service: a stateless layer that validates the prefix, reads the index, applies filters and returns a few results. It holds no data of its own, so any copy can answer.
  • Prefix index (trie or sorted set): read-only between rebuilds, holds the top results per prefix.
  • Log pipeline and build job: collect searches, aggregate counts, build and publish the next index. They never sit on the request path.

Rough capacity estimate

The numbers below are illustrative assumptions chosen for easy arithmetic, not measurements. Replace them with the interviewer's figures.

  • Traffic: 10 million daily users, 10 searches each, is 100 million searches a day.
  • Requests without debounce: about 10 keystrokes per search gives 1 billion requests a day, which is about 11,600 a second (1,000,000,000 divided by 86,400).
  • Requests with debounce: about 4 requests per search gives 400 million a day, about 4,600 a second on average. Assuming a peak of 3 times the average, plan for about 14,000 a second.
  • After the cache: if 80 percent of requests hit the cache (an assumption), the index sees about 2,800 a second at peak.
  • Index size: assume 50 million trie nodes, each holding 5 result ids of 4 bytes (20 bytes) plus about 20 bytes of overhead, so 40 bytes per node and about 2 GB in total. That fits in memory on one machine, so the first scaling step is replication for read capacity, and partitioning is needed only for much larger vocabularies or for region and language.
  • Log volume: 100 million searches at about 100 bytes each is about 10 GB a day of raw logs for the build job.

Typeahead design vs the alternatives

ConcernPrecomputed prefix indexLive database queryClient-side filter
Response timeLowestFinding matches is fast with an index, ranking many matches is slowLowest
Handles millions of termsYesSlowlyNo
Sees a new trend at onceNo (next rebuild)YesYes
Memory neededHighLowLow
Extra moving partsPipeline, indexNoneNone
Best forWeb-scale searchSmall productsShort lists

Use a precomputed index when scale demands it. A database query or a client-side filter is enough for small lists.

Avoiding a new single point of failure

  • Index servers: replicate the index across many servers, since it is read-only between rebuilds. Losing one costs only capacity.
  • Build pipeline: if it fails, keep serving the last good index. Suggestions go stale rather than disappear.
  • Cache: fall back to the index if it is down.
  • Search itself: typeahead is optional, so the search box must still work if it fails.
  • Hot prefixes: a few short prefixes get most of the traffic. If the index is partitioned by first letters, the partitions for popular letters run hotter, so split them further, replicate them more, or rely on the cache for them.
  • Cache after a swap: when a new index replaces the old one, cached answers are from the old index. Give cache entries a short lifetime so they expire within a few minutes, and avoid clearing the whole cache at once, which sends every request to the index together.

You accept slightly stale suggestions in exchange for speed and availability.

Common mistakes

  • Sending a request per keystroke. Debounce and cancel stale requests.
  • Ranking by raw counts only. Old terms dominate. Weight recent searches.
  • Scanning all data per request. Precompute top results per prefix.
  • Rebuilding in place. Build a new index and swap, so readers never see a half-built one.
  • Ignoring bad suggestions. Filter offensive or private terms before they are indexed.
  • Treating it as critical. It should degrade quietly.

How to talk about typeahead in an interview

  • Ask for scale, latency target, and how fresh suggestions must be.
  • Describe the trie with top results at each node, or a sorted set, and the offline pipeline that builds it from search logs.
  • Mention debouncing, caching of short prefixes, and swapping in a new index.
  • Name the trade-off: a precomputed index is very fast but stale until the next rebuild, so you choose the refresh interval to match how quickly trends matter.

Where you meet typeahead in real systems

Search boxes on shops, maps, email and code editors all suggest as you type. Here are three drawn out, the first with configuration you can run, then more examples.

Example 1: Prefix suggestions from a sorted set and an index

Redis can keep terms in a sorted set and read the range that starts with a prefix. PostgreSQL can serve a prefix query from an index built for it. Open the example below to see the picture and the commands.

Config: prefix lookups in Redis and PostgreSQLSetup 5 commands and 1 tableCode no code changes
User typesdebounce 150 msCachecommon prefixesPrefix indextop resultsSuggestionsshown in the box
The client waits for a pause, then asks for suggestions. A cache answers common prefixes. A miss reads the prebuilt index.
# Terms in one sorted set with every score 0, so Redis orders them alphabetically (lexicographically).
# Replace the terms with your own.
ZADD terms 0 car 0 card 0 cardigan 0 care 0 cat 0 cake 0 dog

# All terms that start with "car": from "car" up to, but not including, "cas".
# "[car" means "including car". "(cas" means "excluding cas".
ZRANGEBYLEX terms [car (cas

# Limit the answer to the first 3 matches: offset 0, count 3.
ZRANGEBYLEX terms [car (cas LIMIT 0 3

# For ranking by popularity, keep a second sorted set per prefix whose score is the search count.
ZADD top:card 120 card 45 cardigan 30 cards
ZREVRANGE top:card 0 2 WITHSCORES

The Redis commands were run against a real Redis 7 server: a lexicographic range for a prefix, a limited range and a ranked set. The SQL was run against a real PostgreSQL 16 server. Names and counts are examples. Some Redis releases mark ZRANGEBYLEX and ZREVRANGE as deprecated in favour of ZRANGE with BYLEX or REV options; they still work, but check the documentation for your version.

Example 2: A trie with top results at each node

Each step down the tree adds one letter. The node stores the best few completions, so no search is needed at request time.

rootccacarcard
Following c, a, r, d visits four nodes. Each node stores its top completions, so the answer is read from the last node reached.

Example 3: Building the index from search logs

A background job turns a stream of searches into counts and a new index, which then replaces the old one.

Search logsevery queryAggregatecounts, recent firstBuild indextop results per prefixSwap inno downtime
Search logs are aggregated into counts, a new prefix index is built from them, and the new index is swapped in while the old one keeps serving.

More real-world scenarios

Scenarios 4 to 10 are illustrative patterns, not descriptions of any named company's system.

4. Online shops

Suggestions combine popular queries with product names and categories, and hide items that are out of stock.

5. Maps and places

Suggestions depend on where the user is, so the index is partitioned by region and ranked with distance.

6. Email and contacts

Suggestions come from a small, private list, so the filter runs in the client or on the user's own data.

7. Code editors

Completions come from the symbols in the project, ranked by recent use, computed locally for low delay.

8. Personalised search

A general index is mixed with the user's own history, so a person's frequent searches appear first.

9. Trending and breaking news

Fresh queries are added to a small, fast-updating index that is merged with the big, slower one.

10. Typo tolerance

The index also stores common misspellings or uses edit distance, so "cardgan" still suggests "cardigan".

Tools and managed services

KindNameNotes
Key-value storeRedisSorted sets and range queries for prefixes
Search engineElasticsearch, OpenSearchSuggesters and n-gram analysers
DatabasePostgreSQLPrefix indexes with text_pattern_ops
Log pipelineApache Kafka, Apache SparkAggregate search logs into counts
Edge cacheCDNs and reverse proxiesCache answers for common prefixes

The takeaway

Whenever a design needs answers in tens of milliseconds from a huge dataset, precompute the answer for each prefix in an index and rebuild it on a schedule.

Interview questions

Try answering out loud before you reveal hints. Interviewers care about how you reason, not just the final answer.

  1. 1.

    What data structure would you use for autocomplete, and how do you rank the results?

    medium
  2. 2.

    How do you make suggestions follow trends without rebuilding the whole index every second?

    hard
  3. 3.

    Every keystroke becomes a request. How do you control the load?

    easy
  4. 4.

    The suggestion service is down. What should the user see?

    medium
  5. 5.

    The index no longer fits on one machine. How do you scale it?

    medium
  6. 6.

    Roughly how big is this system? Walk through a back-of-the-envelope estimate.

    medium

Finished this lesson?

Progress is saved on this device. Create a free account to keep it everywhere.

Topics:TypeaheadAutocompleteTriePrefix searchSearch suggestionsCachingCase study

↑ Back to top

Next lesson