Vibe Engines
YouTube
System Design

Design a Search Engine

Step 1 / 9

Learn system design by building a web search engine step by step.

The numbers to beatBM25text relevancePageRankauthoritytop 10shown

The whole design, in writing

Learn system design by building a web search engine step by step. An interactive guide covering the inverted index, query parsing, building the index from crawled pages, ranking with BM25 and PageRank, sharding with scatter-gather retrieval, result caching, and freshness.

Every step of the build above, written out: the problem each piece solves, the option that was taken and the ones that were not, the numbers, and how it fails in production.

The big idea

What is a search engine?

Type a few words and get the ten best pages from billions, ranked by relevance, in a few hundred milliseconds. Two hard problems hide inside: finding the matching documents fast, and ordering them so the most useful is first.

Usertypes a query
New in this step: User.

Flip the data around with an inverted index (term → documents) so matching is a list lookup, not a scan. Then rank the matches by relevance and authority, shard the index for scale, and cache the popular queries.

What the new pieces do

Userclient
Wants the ten most relevant pages out of billions, in a few hundred milliseconds. Relevance and speed together are the whole product.

Step 1 · The skeleton

Query in, matches out

Given a query, you must return documents containing those words. Scanning every page for every query is hopeless at web scale — you’d need to read the entire internet on each search.

Query ServiceInverted Index
New in this step: Query Service, Inverted Index. · swipe to pan the diagram

Return docs containing the query words, from billions of pages, in ~100ms. How do you store the data?

  1. Reading the entire web on every search is hopeless — billions of docs per query. You must precompute where each word lives, not search at query time.

  2. Doc → words answers "what’s in this page?", the wrong question. You’d still scan every doc’s word list to find a term. You need the inverse.

  3. Term → docs turns a query into looking up each word’s postings list and intersecting them — a handful of list ops instead of scanning the web. The single most important idea here.

Stand up a Query Service backed by an Inverted Index: instead of “which words are in this doc?”, store “which docs contain this word?”. A query becomes looking up each term’s document list and intersecting them.

What the new pieces do

Query Servicebackend
Receives the query, coordinates parsing, retrieval and ranking, and returns the results page. The conductor of the read path.
Inverted Indexindex
The core structure: for each term, the list of documents containing it (a postings list). Finding matches becomes intersecting a few lists, not scanning the web.

Back of the envelope

query = intersect postings lists
a few list ops, not a web scan
term → sorted doc-id list
precomputed once at index time
+ positions & frequencies
enable phrase match and relevance scoring

Step 2 · Match the right forms

Parse the query

A user types “Running Shoes” but the index stored “run” and “shoe”. Case, punctuation, stop words and word forms all cause misses unless the query is processed the same way the documents were.

Query ServiceQuery ParserInverted Index
New in this step: Query Parser. · swipe to pan the diagram

A user types "Running Shoes" but the index stored "run" and "shoe". How do you make them match?

  1. Enumerating every case/tense/plural for every word explodes the index and still misses forms you didn’t list. Normalize both sides instead of expanding one.

  2. Tokenize, lowercase, strip stop words and stem the query exactly as the documents were, so "Running" and "run" resolve to the same postings list. Symmetry of analysis is the fix.

  3. Substring matching can’t use the postings lists (slow) and is wrong (matches "run" inside "errand"). The principled fix is identical normalization, not fuzzy scanning.

A Query Parser tokenizes, lowercases, strips stop words and stems terms — applying the exact pipeline used at index time. Now “Running” and “run” resolve to the same postings list, so matching actually works.

What the new pieces do

Query Parserservice
Lowercases, tokenizes, removes stop words and stems the query (“running” → “run”) so it matches the same forms used when the index was built.

Step 3 · Build the index

From pages to postings

The inverted index doesn’t appear by magic — it has to be built from the crawler’s billions of pages, and rebuilt as new pages arrive. Doing that inline with queries would be impossible.

Usertypes a queryCrawlerfetched pagesQuery Serviceparse + serveIndexerbuild the index
New in this step: Crawler, Indexer.

The inverted index must be built from billions of crawled pages and kept current. Where does that happen?

  1. Indexing a document is heavy work; doing it in the query path would make every search wait on parsing pages. Build and serve are opposite workloads — separate them.

  2. The indexer reads crawled docs, runs the same analysis, and writes postings in the background. Separating write-heavy indexing from read-heavy querying lets each scale independently.

  3. Rebuilding billions of postings for each new page is absurdly wasteful. Indexing is incremental — append/merge new postings into segments — not a full rebuild per change.

An offline Indexer pipeline reads crawled documents, runs the same analysis, and writes each term’s postings (doc ids, positions, frequencies) into the index. It runs continuously in the background, separate from serving queries.

What the new pieces do

Crawlersource
Supplies the raw documents to search over (see the web-crawler design). The index is only as fresh and complete as what the crawler delivers.
Indexerworker
Parses crawled pages, extracts terms, and writes postings into the inverted index — the offline pipeline that turns documents into searchable structure.

Step 4 · Which ten first?

Ranking

A common query matches millions of documents. Returning them in index order is useless — the user only looks at the first few, so the order is the entire value of the product.

Query Parsertokenize · normalizeRankerBM25 + PageRankInverted Indexterm → docsDoc Storetitles · snippets
New in this step: Ranker, Doc Store.

A common query matches millions of docs. Returning them in index order is useless. How do you order them?

  1. Raw term frequency rewards keyword-stuffed and long pages and ignores authority — a spam page repeating the word wins. You need match quality and trustworthiness.

  2. Authority without textual relevance returns famous pages that barely match the query. A trusted page on the wrong topic isn’t a good result — you need relevance too.

  3. BM25 asks "does this match the words well?", PageRank asks "is this page trustworthy?". Combining them (plus freshness, quality) is why search beats a keyword grep. The Doc Store then supplies titles/snippets for the winners.

A Ranker scores candidates by textual relevance (TF-IDF/BM25 — how well the terms fit the doc) and authority (PageRank — how important the page is), plus signals like freshness. The Doc Store then supplies titles and snippets for the winners.

  • BM25text relevance
  • PageRankauthority
  • top 10shown

What the new pieces do

Rankerservice
Scores candidate documents by textual relevance (BM25/TF-IDF) and authority (PageRank), then orders them so the best result lands at the top.
Doc Storestore
Holds document metadata and content used to build the title, URL and snippet shown for each result after ranking selects the winners.

Step 5 · Too big for one box

Shard & scatter-gather

The index for the whole web is far too large for a single machine’s memory or disk, and one server can’t evaluate a query against billions of documents in time.

Query ServiceRetrieverIndex Shards
New in this step: Retriever. · swipe to pan the diagram

The whole-web index is far too big for one machine. How do you search billions of docs in time?

  1. Term-sharding creates hotspots on common words and uneven load, and the postings for a popular term still won’t fit one box. Document-sharding spreads work evenly.

  2. Each shard searches its slice in parallel; the retriever fans out (scatter), each returns its local top results, and they’re merged (gather). You wait for the slowest shard, not the sum — latency stays bounded as the corpus grows.

  3. Replicas add throughput but every replica still can’t fit or evaluate the whole-web index in time. You must partition the index across machines, then replicate each shard.

Shard the index by document across many machines. A Retriever sends the query to every shard in parallel (scatter), each returns its local top candidates, and the retriever gathers and merges them for ranking. Latency stays bounded as the corpus grows.

  • by-documentsharding
  • parallelshard search
  • mergetop results

What the new pieces do

Retrieverservice
Fans a query out to every index shard in parallel, gathers each shard’s top candidates, and merges them — the pattern that makes billions of docs searchable.

Back of the envelope

shard by document
each shard searches a slice in parallel
latency = slowest shard
not the sum — bounded as the corpus grows
+ replicate each shard
adds throughput and fault tolerance

Step 6 · The same searches

Cache hot queries

A huge share of searches are the same popular queries repeated endlessly. Re-running the full parse → scatter-gather → rank pipeline for each identical query wastes enormous compute.

Query ServiceRetrieverRankerIndex ShardsIndexerResult Cache
New in this step: Result Cache. · swipe to pan the diagram

A huge share of searches are the same popular queries repeated endlessly. How do you save that compute?

  1. Scaling the fleet to re-run identical popular queries burns compute on work you already did. When the same input repeats, recompute is the waste to eliminate, not to scale.

  2. Postings caching helps retrieval but still re-runs parse → scatter-gather → rank → merge for every repeat of a head query. You can skip the whole pipeline by caching the finished result.

  3. Search traffic follows a steep power law, so a modest result cache answers a large fraction of queries in ~1ms, sparing the index and ranking fleet for the rare, novel long-tail queries.

Cache the result pages for popular queries. Search traffic follows a steep power law, so a modest Result Cache answers a large fraction of queries in a millisecond, sparing the index and ranking fleet for the long tail.

What the new pieces do

Result Cachecache
Caches the result pages for popular queries. Search traffic is highly skewed, so a small cache serves a large share of queries instantly.

Back of the envelope

head queries ≫ tail
a steep power law in search traffic
small cache ⇒ big hit rate
a large share of queries answered in ~1ms
miss ⇒ full pipeline
spend retrieval budget on novel queries

Step 7 · Stay current

Freshness & the sharp edges

News breaks and pages change constantly, but rebuilding a web-scale index takes time. Users also expect spelling correction, synonyms, and protection from spam pages gaming the ranking.

UserCrawlerQuery ServiceQuery ParserRetrieverRankerIndex ShardsDoc StoreIndexerResult Cache
The system as it stands at this step. · swipe to pan the diagram

Run a small, fast fresh index for recent content merged with the big base index at query time. Layer query understanding (spell-correct, synonyms) before retrieval, and add spam/quality signals to ranking so manipulated pages don’t win.

You did it

You just designed a search engine.

UserCrawlerQuery ServiceQuery ParserRetrieverRankerIndex ShardsDoc StoreIndexerResult Cache
The finished design, end to end. · swipe to pan the diagram

Everything you assembled, in order

  • An inverted index turns search from a scan into term-list lookups.
  • Query parsing applies the same analysis as indexing so terms actually match.
  • An offline indexer builds postings from crawled pages, separate from serving.
  • Ranking combines text relevance (BM25) with authority (PageRank).
  • Document-sharding plus scatter-gather retrieval scales to billions of docs.
  • A result cache exploits skewed traffic to answer head queries instantly.
  • A fresh index, query understanding and spam signals keep results current and clean.

Where an interviewer pokes next

Getting the boxes right is the easy half. These are the questions that separate a candidate who drew the diagram from one who has run the thing. Answer each one out loud before you open it.

  1. How do you intersect huge postings lists fast for multi-word queries?

    Store postings sorted by doc id and intersect with skip pointers (galloping search), starting from the rarest term so the smallest list drives the walk. Add early termination (WAND / block-max) so you stop once no unseen doc can crack the top-k. You never fully materialize the intersection of common terms.

  2. How does the index update without rebuilding everything?

    Segment-based indexing (à la Lucene): new docs go into small immutable segments searched alongside the big ones and merged in the background; deletes are tombstones applied at query time. Near-real-time updates without rewriting the whole index — the freshness/scale split from step 7.

  3. How are spelling correction and synonyms handled?

    In a query-understanding layer before retrieval: a spell corrector (edit-distance against a term dictionary weighted by query logs) rewrites/suggests, and synonym expansion adds related terms (learned from click data). It’s kept separate from the index so you can iterate without re-indexing.

  4. Scatter-gather waits for the slowest shard — how do you tame tail latency?

    Replicate each shard and issue hedged requests to more than one replica, taking the first to answer; set a deadline after which you return partial results from the shards that responded. A few missing shards cost a little recall, not a hung query — graceful degradation is built in.

  5. How do you stop spam pages gaming the ranking?

    Ranking is an arms race: combine many quality/authority signals (PageRank, spam classifiers, site reputation, behavior signals) so no single stuffable factor dominates, keep the weights secret and frequently retrained, and run link-spam / content-farm detection offline to feed penalties into the ranker.

Check yourself — the answers, and why

Eight steps in, these are the calls you should be able to make cold. Pick one, then read why.

  1. The inverted index maps…

    • Doc → its words
    • Term → the docs containing it
    • Query → user

    Term→docs turns search into postings-list lookups instead of scanning every document.

  2. Queries use the same analysis as documents so that…

    • Queries run faster
    • "Running" matches the indexed "run"
    • The cache is smaller

    Symmetry of analysis — mismatched normalization is the top cause of missed matches.

  3. Good ranking combines…

    • Term frequency only
    • Text relevance (BM25) and authority (PageRank)
    • Alphabetical order

    BM25 = does it match the words; PageRank = is the page trustworthy. Together they beat keyword grep.

  4. Scatter-gather over a document-sharded index means latency is…

    • The sum of all shards
    • Bounded by the slowest shard
    • One shard only

    All shards search in parallel; you wait for the slowest, so adding shards scales corpus, not latency.

  5. A result cache works because search traffic is…

    • Uniform
    • Steeply skewed toward head queries
    • All unique

    A small cache of popular query results answers a large share of traffic in ~1ms.

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

What it must do

Agree on these before drawing a single box.

  • Search: given a query, return the ten most relevant documents out of billions, in a few hundred ms.
  • Match: find documents containing the query terms via an inverted index — term → docs.
  • Understand the query: tokenize, lowercase, strip stop words and stem so “Running” matches the indexed “run”.
  • Rank: order matches by textual relevance (BM25) and authority (PageRank); show the top 10.
  • Stay fresh: newly crawled pages become searchable, with spelling correction and synonyms improving recall.

The qualities that shape everything

Each one names the mechanism that buys it.

Match without scanning the web
An inverted index maps each term to its postings list, so a query is a handful of list intersections instead of reading billions of docs.
Queries match the stored forms
The Query Parser runs the exact analysis used at index time — tokenize, lowercase, stop-word, stem — so “Running Shoes” resolves to the same postings as “run”/“shoe”.
Indexing never slows a query
An offline Indexer builds postings from crawled pages in the background, separate from the read path — build offline, serve online.
The best result lands first
A Ranker combines textual relevance (BM25) with page authority (PageRank) plus freshness — order is the whole product.
Search billions of docs in time
Shard the index by document and scatter-gather: fan the query to every shard in parallel, gather each shard’s top candidates, merge — latency is the slowest shard, not the sum.
Absorb the repeated head queries
A Result Cache exploits steeply skewed traffic — a small cache answers a large share of queries in ~1ms, sparing the retrieval fleet.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

Inverted index (term → docs) over a forward index (doc → words)

A forward index answers “what’s in this page?” — you’d still scan every doc’s word list to find a term. Inverting it turns a query into a few precomputed list lookups instead of reading the web.

Offline incremental indexer over building postings on the fly per query

Indexing a document is heavy; doing it in the query path makes every search wait on parsing pages. Build-heavy indexing and read-heavy querying are opposite workloads — separate them so each scales.

BM25 relevance × PageRank authority over raw term frequency alone

Sorting by how often a term appears rewards keyword-stuffed and long pages and ignores trust — a spam page repeating the word wins. Combining match quality with authority is why search beats a keyword grep.

Shard by document + scatter-gather over sharding the index by term

Term-sharding creates hotspots on common words and the postings for a popular term still won’t fit one box. Document-sharding spreads work evenly and you wait for the slowest shard, not the sum.

Cache whole result pages over scaling the retrieval fleet to re-run head queries

Re-running identical popular queries burns compute on work already done. Search traffic follows a steep power law, so a modest result cache answers a large share in ~1ms — spend retrieval budget on the novel long tail.

What this teaches

Learn system design by building a web search engine step by step. An interactive guide covering the inverted index, query parsing, building the index from crawled pages, ranking with BM25 and PageRank, sharding with scatter-gather retrieval, result caching, and freshness.

Key takeaways

  • An inverted index turns search from a scan into term-list lookups.
  • Query parsing applies the same analysis as indexing so terms actually match.
  • An offline indexer builds postings from crawled pages, separate from serving.
  • Ranking combines text relevance (BM25) with authority (PageRank).
  • Document-sharding plus scatter-gather retrieval scales to billions of docs.
  • A result cache exploits skewed traffic to answer head queries instantly.
  • A fresh index, query understanding and spam signals keep results current and clean.

Concepts covered

  • What is a search engine?
  • Query in, matches out
  • Parse the query
  • From pages to postings
  • Ranking
  • Shard & scatter-gather
  • Cache hot queries
  • Freshness & the sharp edges
built to be ranked, not memorized — make the calls, drop the cache, run the gauntlet.
Finished this one? 0 / 65 System Designs done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More System Designs