Markdown Editor

Search Autocomplete System Design Template (Reference Design)

Typeahead: trie/FST/edge n-gram index, popularity and recency ranking, query-log pipeline, edge cache, latency budget, safety

How to use: Use when adding search suggestions. Start from the latency budget and size the index from distinct queries above a threshold. The main pitfall is serving harmful or personal suggestions; filter in the pipeline and again at serve time.

Preview

System Design: [Search autocomplete name]

Reference design for search typeahead (autocomplete): as the user types, the service returns the most useful completions for the prefix within tens of milliseconds. It covers prefix indexes (trie, finite state transducer, edge n-grams), ranking by popularity and recency, the data pipeline from query logs, edge caching, the latency budget, personalisation and abuse filtering. It follows the structure of the System Design Document template and is pre-filled with a worked design to adapt. Values marked Example are assumptions: replace them and recompute.

Document control

FieldValue
Document ID[SDD-AC-001]
System / feature[Search suggestions]
Version[0.1]
Status[Draft / In review / Approved / Implemented / Superseded]
Author(s)[@author]
Reviewers[@reviewer-1], [@reviewer-2]
Last updatedYYYY-MM-DD
Related[Search PRD], [Content policy for suggestions], [Privacy review]

Approvals

RoleNameDecisionDate
Tech lead[@name][Approved / Changes requested]YYYY-MM-DD
Staff / principal engineer[@name][Decision]YYYY-MM-DD
SRE / operations[@name][Decision]YYYY-MM-DD
Trust and safety / policy[@name][Decision]YYYY-MM-DD
Privacy[@name][Decision]YYYY-MM-DD

Revision history

VersionDateAuthorChange summary
0.1YYYY-MM-DD[@name]First draft for design review
0.2YYYY-MM-DD[@name]Example: Added trending layer with 5-minute windows
0.3YYYY-MM-DD[@name]Example: Moved personal history to the device by default
1.0YYYY-MM-DD[@name]Example: Approved

Contents

1. Overview

1.1 Problem statement

[Example: Today suggestions come from a LIKE 'prefix%' query on the product database. p99 is 380 ms, suggestions are alphabetical rather than useful, breaking news terms take a day to appear, and last month an offensive suggestion was screenshotted and shared widely.]

1.2 Proposed solution

[Example: An offline pipeline aggregates anonymised query logs hourly into scored suggestions, filters them against policy lists, and builds an immutable in-memory prefix index (a trie with the top completions cached at each node). Suggest servers load the index and answer prefix requests in under 5 ms. A streaming layer adds trending queries within minutes. Responses for short, popular prefixes are cached at the CDN edge for 5 minutes. Personal recent searches are blended in on the client from local history.]

1.3 Decisions requested from reviewers

IDQuestionRecommended optionSection
Q-01Example: Trie with top-k per node, FST, or search-engine edge n-grams?Trie with top-k per node7.1, 10
Q-02Example: How fresh must suggestions be?Hourly base index + 5-minute trending layer7.3
Q-03Example: Server-side personal history?No by default; device-local history, opt-in sync7.5
Q-04Example: Cache at edge for which prefixes?Length 1 to 3, non-personalised responses only7.4
[Q-nn][Question][Option][Section]

2. Requirements

2.1 Functional requirements

IDRequirementPriority
FR-01Example: Return up to 10 completions for a prefix, ranked by usefulnessMust
FR-02Example: Support per-locale suggestions (language and market)Must
FR-03Example: Reflect trending queries within 15 minutesShould
FR-04Example: Never suggest terms on the policy blocklistMust
FR-05Example: Blend the user's recent searches at the top, removable by the userShould
FR-06Example: Tolerate one typo for prefixes of 4+ charactersCould
FR-07Example: Remove a reported suggestion globally within 10 minutesMust
[FR-nn][Requirement][Must / Should / Could]

2.2 Non-functional requirements

IDQualityTargetMeasured as
NFR-01LatencyExample: Server p99 at or below 20 ms; perceived p95 at or below 100 msServer metrics, client RUM
NFR-02AvailabilityExample: 99.9%; search must work without suggestionsSynthetic checks
NFR-03FreshnessExample: Base index at most 2 h old; trending at most 15 minIndex build timestamp
NFR-04SafetyExample: Zero blocklisted suggestions servedAudit sampling of served suggestions
NFR-05PrivacyExample: No suggestion derived from fewer than 50 distinct usersPipeline threshold test
[NFR-nn][Quality][Target][Measurement]

2.3 Out of scope

  • [Example: the search results page itself]
  • [Example: rich entity cards in the dropdown]
  • [Example: voice query suggestions]
  • [Item deferred, with the release that will take it]

3. Capacity estimation

3.1 Assumptions

InputSymbolValueSource
Daily active searchersUUExample: 100 millionAnalytics
Searches per user per dayqqExample: 5Analytics
Suggest requests per search after 100 ms debouncerrExample: 4Client telemetry
Peak to average factorkkExample: 3Traffic history
Edge cache hit ratiohhExample: 60%Pilot measurement
Distinct suggestions kept (per locale set)NNExample: 20 millionLog analysis above threshold
Average suggestion lengthℓ\ellExample: 20 charactersLog analysis
Distinct prefix nodes as share of total charactersσ\sigmaExample: 0.3Trie build on a sample

3.2 Request rate

QPS=U×q×r86 400=108×5×486 400≈23 000 req/s,peak≈69 000 req/sQPS = \frac{U \times q \times r}{86\,400} = \frac{10^{8} \times 5 \times 4}{86\,400} \approx 23\,000 \ \text{req/s}, \qquad \text{peak} \approx 69\,000 \ \text{req/s}

Origin load after the edge cache:

QPSorigin=(1−h)×69 000≈27 600 req/s at peakQPS_{origin} = (1 - h) \times 69\,000 \approx 27\,600 \ \text{req/s at peak}

3.3 Index size

Prefix nodes:

P=N×ℓ×σ=2×107×20×0.3=1.2×108 nodesP = N \times \ell \times \sigma = 2 \times 10^{7} \times 20 \times 0.3 = 1.2 \times 10^{8} \ \text{nodes}

With a top-10 list of 4-byte suggestion IDs (40 B) plus about 24 B of node structure:

Mtrie≈1.2×108×64 B≈7.7 GBM_{trie} \approx 1.2 \times 10^{8} \times 64 \ \text{B} \approx 7.7 \ \text{GB}

plus suggestion strings and scores (2×107×322 \times 10^{7} \times 32 B ≈0.64\approx 0.64 GB), about 8.3 GB per replica. Each suggest server holds a full replica, so no cross-node calls are needed on the request path.

3.4 Pipeline volume

Lday=U×q=5×108 search events/day×200 B≈100 GB/dayL_{day} = U \times q = 5 \times 10^{8} \ \text{search events/day} \times 200 \ \text{B} \approx 100 \ \text{GB/day}

3.5 Summary

QuantityEstimateDesign consequence
Requests~69 000/s peak, ~28 000/s at originSmall fleet of in-memory servers behind edge cache
Index~8.3 GB per replicaFull replica per server; no sharding needed yet
Log volume~100 GB/dayHourly batch aggregation is cheap
Latency20 ms server budgetNo disk or network hop on the hot path

4. API design

4.1 Endpoints

MethodPathPurposeAuthCacheable
GET/v1/suggest?q={prefix}&locale={loc}&n=10Suggestions for a prefixNone or sessionYes, for anonymous requests
POST/v1/suggest/feedbackReport a suggestionSessionNo
POST/internal/v1/blocklistAdd a term or pattern (policy team)Admin roleNo

4.2 Request and response examples

The prefix is normalised (case-folded, whitespace collapsed) on the client and the server so cache keys match:

GET /v1/suggest?q=wint&locale=en-GB&n=8 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=300
Vary: Accept-Encoding

{"q": "wint", "indexVersion": "2026-03-14T09", "suggestions": [{"text": "winter coats", "kind": "query"}, {"text": "winter tyres", "kind": "query"}, {"text": "winter olympics schedule", "kind": "trending"}]}

4.3 Errors and limits

StatusProblem typeWhen
400prefix-too-longPrefix over 100 characters
429rate-limitedClient over 20 requests/s; Retry-After set

Clients treat any error or a response slower than 300 ms as "no suggestions"; typing is never blocked.

5. Data model

5.1 Entities

The pipeline turns raw query events into scored suggestions; an index build packages them for serving.

5.2 Storage choices

DataStoreKeyMain queriesWhy
Query eventsEvent stream, then data lake (partitioned by hour)TimeBatch aggregationCheap, append-only
Query statsData warehouse tableQuery, locale, dayScore computationSQL-friendly batch
Index buildsObject storage, versioned filesversionDownload by serversImmutable artifacts, easy rollback
Trending countersIn-memory stream processor stateQuery, locale, windowTop-k per windowMinutes-level freshness
Block rulesRelational database, replicated to serversrule_idAll active rulesAudited, small

6. High-level design

The serving path is read-only and in memory; all heavy work happens in the pipeline.

ComponentResponsibilityScales by
Suggest serversLook up prefix, merge trending, filter, return top NReplicas (each holds full index)
Stream processorCount queries per 5-minute window, detect spikesPartitions by query hash
Aggregation and scoringCompute decayed popularity per query and localeBatch cluster
Policy filterApply block rules, privacy thresholdsBatch step
Index builderBuild trie with top-k per node, validate, publishSingle batch job per locale group
[Component][Responsibility][Scaling unit]

7. Detailed design

7.1 Prefix index options

StructureLookupMemoryUpdatesFit
Trie with top-k cached per nodeO(prefix length) then read listLargestRebuild or careful in-placeChosen: fastest, simple serving
Finite state transducer (FST)O(prefix length) plus traversal for top-kSmallest (shares prefixes and suffixes)Immutable, rebuildGood when memory bound; top-k needs weighted traversal
Edge n-grams in a search engineInverted index queryLarge (every prefix indexed)Near real timeGood when suggestions need full-text features and filters
Sorted array + binary searchO(log N) then scanSmallRebuildSimple baseline; top-k needs scan of range

The trie stores, at each node, the IDs of the 10 highest-scoring suggestions in its subtree, computed bottom-up during the build. A lookup walks the prefix and returns that list without exploring the subtree.

7.2 Ranking

Base score for query xx in locale ℓ\ell uses exponentially decayed daily counts with half-life hh (Example: 7 days):

S(x)=∑d=0Dcx,d⋅2−d/hS(x) = \sum_{d=0}^{D} c_{x,d} \cdot 2^{-d/h}

At serve time, the trending layer adds a boost when the last window greatly exceeds the expected rate:

boost(x)=max⁡(0, log⁡2cx, 5min+1μx, 5min+1)\text{boost}(x) = \max\left(0,\ \log_2 \frac{c_{x,\,5min} + 1}{\mu_{x,\,5min} + 1}\right)

where μ\mu is the average 5-minute count over the last 7 days. A query seen 16 times more than usual gets a boost of about 4 score units; the weight of the boost against SS is tuned with online experiments. Final order also applies diversity (no more than 3 suggestions sharing the same first two words).

7.3 Data pipeline

StageFrequencyWorkOutput
IngestContinuousNormalise query, drop events from known bots, hash user ID with rotating saltEvents in lake and stream
AggregateHourlyCount per query, locale, day; count distinct usersQuery stats
ThresholdHourlyKeep queries with at least 50 distinct users in 30 daysCandidate suggestions
FilterHourlyApply block rules, PII detectors (emails, phone numbers, ID numbers)Clean suggestions
BuildHourlyBuild trie per locale group, compute checksums, run golden-prefix testsIndex version
PublishHourlyUpload; servers download, load into memory, swap atomicallyServing index

Servers keep the previous version in memory until the new one passes a self-test, so a bad build never serves.

7.4 Suggest request (critical path) and caching

Short prefixes are the most requested and the least personal, so they are cached at the edge; longer prefixes go to origin.

Clients also keep a small in-memory cache: if "win" returned 10 results and the user types "wint", the client can filter locally while the request is in flight.

7.5 Personalisation

Personal recent searches stay on the device (local storage, last 50 entries, user-clearable) and are blended on the client by prefix match, which keeps edge responses cacheable and avoids server-side profiles. Signed-in users may opt in to sync history; synced history is encrypted at rest, deletable, and never used to train global suggestions.

7.6 Abuse and safety filtering

  • Block rules: exact terms, patterns and entity lists maintained by the policy team; applied in the pipeline and again at serve time so a new rule takes effect within the 10-minute rule-sync interval without a rebuild.
  • Manipulation: coordinated query injection is limited by the distinct-user threshold, bot filtering and caps on the trending boost per source network.
  • Privacy: the threshold and PII detectors prevent rare personal queries (names with addresses, account numbers) from becoming suggestions.

7.7 Consistency model

All servers converge on the same index version within one publish cycle; during rollout two versions may serve for up to 10 minutes, which users cannot notice. Block-rule removals are the only change with a hard deadline (FR-07) and are pushed separately from index builds.

8. Scalability and performance

ConcernApproachLimit before redesign
Request rateStateless replicas, edge cacheExample: ~5 000 req/s per server, so 6 servers for peak origin load plus 2 spare
Index memoryFull replica per serverWhen index exceeds ~50% of server memory, shard by locale group
Build timeParallel per locale groupHourly cadence needs builds under 20 min
Long-tail prefixesServed from origin; edge only for short ones[Limit]

Latency budget, keystroke to rendered suggestions (target p95 100 ms):

StepBudget
Debounce0 ms after last pause (not counted)
Network to edge (round trip)30 ms
Edge to origin on miss (round trip)25 ms
Server processing (lookup, merge, filter)5 ms
Client blend and render10 ms
Headroom30 ms

9. Reliability, security and operations

9.1 Failure modes

FailureImpactDetectionMitigation
Bad index buildWrong or empty suggestionsGolden-prefix tests, size and checksum checksBuild rejected; servers keep previous version
Pipeline delayedStale suggestionsIndex age metricServe last good index; trending layer still fresh
Trending stream downNo trending boostsWindow lag metricServe base index only
Edge cache poisoning by personal dataLeak of one user's suggestionsResponse auditOnly anonymous, non-personalised responses are cacheable (private otherwise)
Suggest servers downNo suggestionsSynthetic checksSearch box works without them; client timeout 300 ms
[Failure][Impact][Signal][Mitigation]

9.2 Security, privacy and abuse

ThreatControl
Offensive or defamatory suggestionsBlock rules, reporting with 10-minute takedown, human review queue
Suggestion manipulation by botsDistinct-user threshold, bot filtering, trending caps
Personal data in suggestionsThreshold of 50 users, PII detectors, hashed user IDs with rotating salt
Scraping of the suggestion corpusRate limits per IP; corpus is low sensitivity by design
Retention of query logsExample: Raw events 30 days, aggregates 13 months
[Threat][Control]

9.3 Observability

SignalMetric or logAlert threshold
Server latencyp99Above 20 ms for 10 min
Perceived latencyClient RUM p95Above 100 ms for 30 min
Index ageNow minus build timeAbove 2 h
Suggestion acceptanceShare of searches that used a suggestionDrop of 10% vs. baseline
SafetyReports per million impressionsSpike above 3x baseline

9.4 Cost estimate

ItemUnit costQuantityMonthly cost
Suggest servers (32 GB RAM)[$/node-month]Example: 12 per region[$]
CDN requests[$/million]Example: ~1.2 billion edge hits/day[$]
Pipeline compute[$/hour]24 builds/day[$]
Data lake storage[$/TB-month]Example: 3 TB (30 days raw)[$]
Total[$]

10. Trade-offs and alternatives

DecisionOptionsChosenWhyWhat we give up
Index structureTrie top-k; FST; edge n-grams in search engineTrie top-kConstant-time top-k, simplest hot pathMore memory than FST
FreshnessReal-time index updates; hourly rebuild + trending layerHourly + trendingImmutable builds are safe and testable; trending covers newsTwo layers to merge
PersonalisationServer profiles; device-local historyDevice-localPrivacy, edge cacheabilityNo cross-device history without opt-in
CachingNo edge cache; cache all; cache short prefixesShort prefixesMost traffic at lowest costLong prefixes always hit origin
Typo toleranceNone; fuzzy trie traversal; separate spell indexDeferred (Could)Complexity versus small gain at launchFewer results for misspellings
[Decision][Options][Chosen][Why][Cost]

11. Delivery plan and risks

11.1 Milestones

MilestoneScopeExit criterionTarget date
M1Pipeline and daily index, one localeGolden-prefix tests pass; p99 under 20 msYYYY-MM-DD
M2Hourly builds, edge cache, all localesAcceptance rate up vs. old system in A/BYYYY-MM-DD
M3Trending layer and reporting flowTrending visible within 15 min; takedown under 10 minYYYY-MM-DD
M4Device-local personal historyPrivacy review signedYYYY-MM-DD

11.2 Rollout and rollback

[Example: A/B test against the old endpoint for 2 weeks per locale. Rollback flips the client config back to the old endpoint; index rollback pins servers to a previous version.]

11.3 Risks

IDRiskLikelihoodImpactMitigationOwner
R-01Example: Harmful suggestion goes viralLowHighDual filtering, fast takedown, on-call policy contact[@name]
R-02Example: Index outgrows server memoryMediumMediumShard by locale group; FST evaluation ready[@name]
R-03Example: Trending boost amplifies manipulationMediumMediumCaps per source network, human review of top trending[@name]
[R-nn][Risk][L / M / H][L / M / H][Mitigation][@name]

12. Appendices

12.1 Open questions

IDQuestionOwnerDue
OQ-01Example: Do we suggest product entities as well as queries?[@name]YYYY-MM-DD
OQ-02Example: Which locales share an index?[@name]YYYY-MM-DD
[OQ-nn][Question][@name]YYYY-MM-DD

12.2 Glossary

TermMeaning
PrefixCharacters typed so far
TrieTree keyed by characters where each path is a prefix
FSTFinite state transducer: compact automaton mapping strings to values
Edge n-gramIndexing every leading substring of a term
DebounceWaiting for a short pause in typing before sending a request
[Term][Meaning]

12.3 References

ReferenceUse
RFC 9111 HTTP CachingEdge caching rules in 7.4
RFC 9110 HTTP SemanticsAPI and Retry-After
[Search engine documentation on completion suggesters]Alternative in 7.1
[Internal content policy for suggestions]Filtering in 7.6

Standard and licence note

Based on common industry practice for search autocomplete design and on the HTTP specifications cited in 12.3. This is a reference design to adapt, with illustrative numbers. Original text written for this collection. Template licence: MIT.

Related templates