1. What It Is
Semantic search and recommendations increasingly rely on vector embeddings and approximate nearest-neighbor indexes. We trade exact recall for speed at billion-vector scale.
What:
A fixed-length dense vector (typically 256–1536 floats) produced by a neural embedding model that maps text, images, or user behavior into a semantic space where similar items are geometrically close.
Primary purpose:
Enable similarity search — "find items most like this query" — at scale using approximate nearest neighbor (ANN) indexes instead of brute-force comparison.
Usually used for:
Recommendation candidate generation, semantic search, RAG retrieval, duplicate detection, image similarity, and personalization features.
2. Core Mental Model
Embeddings turn "find similar meaning" into "find nearest points in high-dimensional space." ANN indexes trade perfect accuracy for speed — interview answer: retrieve candidates with ANN, rerank with a heavier model.
📐 Embedding
Model encodes input → float vector. Same model version must encode query and corpus for meaningful distance.
🔍 ANN search
Graph (HNSW) or cluster-probe (IVF) skips most vectors; returns top-K approximate neighbors in sub-linear time.
🔀 Hybrid retrieval
Combine sparse BM25 (keyword) + dense vector scores — weighted sum or reciprocal rank fusion (RRF).
In the room
Say "approximate" loudly — ANN indexes (HNSW, IVF) sacrifice perfect recall for latency. Mention embedding model choice, re-ranking with a cross-encoder, and hybrid search (BM25 + vectors) for production quality.
3. Why It Matters in HLD
Vector search finds nearest neighbors in embedding space — core to RAG, recommendations, and semantic search. Three lenses:
Needed When:
Catalogs exceed brute-force scan (millions+ vectors), queries are semantic not lexical, or personalization requires user/item similarity in embedding space.
Avoids:
Full-table cosine scans, keyword-only search missing synonyms, and cold-start recommendations with zero interaction history (content-based embeddings).
Optimizes For:
Retrieval latency (p99 < 50ms), recall@K for downstream rerankers, and index memory efficiency at billion-vector scale.
4. Architecture & Data Flow
Walk RAG retrieval as interview steps. Step 1 — Embed: chunk documents, generate vectors via embedding model. Step 2 — Index: insert into ANN index (HNSW, IVF). Step 3 — Query: embed user question, k-NN search returns top-k chunks. Step 4 — Augment: inject chunks into LLM prompt context. Step 5 — Filter: metadata pre-filter before ANN to reduce search space.
Cosine similarity computation
import numpy as np
def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
# Pre-normalize vectors at index time → cosine == dot product (faster ANN)
def normalize(v: np.ndarray) -> np.ndarray:
return v / np.linalg.norm(v)
# Hybrid score (common interview pattern)
final_score = 0.3 * bm25_score + 0.7 * cosine_simIn the room
Separate embedding generation (batch/offline) from query-time ANN — say HNSW for low-latency recall and mention metadata filters before vector search.
5. Key Characteristics
HNSW vs IVF, cosine vs dot product, dimension trade-offs — we compare:
- Similarity metrics — pick one and stay consistent across index and query:
| Metric | Formula | When to Use |
|---|---|---|
| Cosine similarity | dot(a,b) / (||a|| x ||b||) |
|
| Dot product | Σ aᵢ x bᵢ |
|
| L2 (Euclidean) distance | √Σ(aᵢ − bᵢ)² |
|
- ANN index families — the index choice drives latency, memory, and recall:
| Index | Mechanic | Tradeoff |
|---|---|---|
| HNSW (Hierarchical NSW) |
|
|
| IVF (Inverted File) | K-means clusters → probe nearest centroids only |
|
| Product Quantization (PQ) | Compress vectors into sub-codebooks |
|
| FAISS / Milvus / Pinecone | Production libraries combining HNSW + IVF + PQ + GPU | Managed vs self-hosted ops tradeoff |
- Dimensionality: 384–768 common for sentence transformers; 1536 for OpenAI ada; higher dims ≠ always better — match model to use case.
- Sharding: partition index by category, geography, or consistent hash; fan-out query to shards, merge top-K globally.
- Freshness: new items need embedding + incremental index insert; batch nightly rebuild vs online HNSW insert trade latency vs consistency.
6. Strategic Tradeoffs
Semantic recall trades index build cost, memory, and approximate accuracy — we state both:
| Benefit | Cost |
|---|---|
| Semantic retrieval — finds conceptually similar items even when keywords do not match |
|
| Sub-100ms ANN at billion scale — HNSW/IVF avoids brute-force O(n) scan |
|
Two-stage retrieval is the standard interview pattern: ANN returns 200–1000 cheap candidates; a cross-encoder or learning-to-rank model reranks to top 10–20. Never run a cross-encoder on the full billion-item corpus.
7. Failure / Bottleneck Awareness
Stale embeddings, cold-start, and hallucination from bad retrieval — we name mitigations:
Problem: IVF with nprobe=1 on a skewed cluster misses the true nearest neighbor; users see irrelevant recommendations.
Mitigation: Benchmark recall@K on held-out queries; increase nprobe or HNSW ef_search; A/B test recall vs latency.
Problem: Query encoded with v2 model, index built with v1 — distances are meaningless.
Mitigation: Dual-write during migration; version tag on index shards; blue/green reindex before cutover.
Problem: 1B x 768-dim x 4 bytes ≈ 3 TB raw vectors before HNSW graph overhead.
Mitigation: Product quantization (PQ), int8 scalar quantization, tier hot catalog in RAM + cold on disk (DiskANN), or shard across nodes.
8. Common HLD Usage
RAG chatbots, product recommendations, and image similarity use vector search:
| Production System | Pattern | Rationale |
|---|---|---|
| Spotify / Netflix recommendations | User + item embeddings → ANN candidate retrieval → rerank |
|
| RAG document QA | Chunk embeddings in vector DB → top-K retrieval → LLM context | Semantic search finds relevant paragraphs keyword search misses. |
| E-commerce search | Hybrid BM25 + dense vector with score fusion |
|
9. Decision Signals
Add vector DB when similarity search on embeddings is the core query pattern:
- Semantic similarity matters more than exact keyword match (RAG, "similar products").
- Catalog > 100K items where brute-force scan is too slow.
- Cold-start content — embed item metadata (title, tags) for recommendations before interaction data exists.
- Multimodal search — image + text in shared embedding space.
- Exact match suffices (SKU lookup, user_id fetch) — B-tree index wins.
- Corpus fits in memory for brute-force (< 50K vectors) — HNSW overhead not justified.
- Interpretability required — "why this result?" is harder with dense vectors than BM25 term overlap.
11. Deep Dive (Optional)
HNSW Internals (Interview Sketch)
Hierarchical Navigable Small World builds a multi-layer graph. Layer 0 contains every vector with dense local links. Upper layers are subsamples with longer jumps. Search starts at the entry point in the top sparse layer, greedily moves to the nearest neighbor until stuck, drops to the next layer, repeats until layer 0, then expands a candidate list controlled by ef_search.
- ef_construction (build time): higher → better graph quality, slower index build.
- ef_search (query time): higher → better recall, higher latency.
- M (max neighbors per node): 16–48 typical; higher M → more RAM, better recall.
IVF + PQ Memory Math
IVF with 4096 centroids partitions vectors into clusters. At query time, probe the nearest nprobe centroids (e.g., 32 of 4096) — search only ~1% of the corpus. Product Quantization splits each 768-dim vector into 96 sub-vectors of 8 dims, each mapped to one of 256 centroids (1 byte each) → 96 bytes vs 3072 bytes raw, with approximate distance via lookup tables.
Hybrid Sparse + Dense Retrieval
# Reciprocal Rank Fusion (RRF) — no score normalization needed
def rrf_score(rank_sparse, rank_dense, k=60):
return 1/(k + rank_sparse) + 1/(k + rank_dense)
# Pipeline:
# 1. BM25 top-100 from Elasticsearch
# 2. ANN top-100 from Milvus/FAISS
# 3. Merge by doc_id, compute RRF, return top-20
# 4. Cross-encoder rerank top-20 → final top-10Sparse catches exact entity names and SKUs; dense catches paraphrases ("laptop" ↔ "notebook computer"). Problem #101 extends this with a learning-to-rank model on hand-crafted + embedding features.
RAG Chunking Strategy
For problem #111: split documents into 256–512 token chunks with 50-token overlap; embed each chunk; store chunk_id → (doc_id, offset, vector). At query time, retrieve top-K chunks, dedupe by doc_id, pass to LLM with citation metadata. Re-rank chunks with a cross-encoder before context assembly to reduce hallucination surface.
FAISS Quick Reference
IndexFlatL2— exact brute force; baseline for recall benchmarks.IndexIVFPQ— IVF + PQ; billion-scale with RAM constraints.IndexHNSWFlat— HNSW without compression; best recall/latency for RAM-rich deployments.- GPU indexes (
GpuIndexIVFPQ) for batch embedding ingestion and high-QPS serving.
Review
How helpful was this walkthrough?
Click a star to rate. We actively use this feedback to refine and update our system design content.
Discussion
Share your thoughts, ask questions, or help others.