Module 4: Proximity Search
2. kNN Conceptually: The K Nearest Neighbors
Overview
The kNN (k-Nearest Neighbors) algorithm is the conceptual foundation of all proximity search: given N vectors, find the K closest to the query. Here you'll see how it works conceptually and why exhaustive search (checking every vector) doesn't scale.
What is kNN?
Definition: Given a query vector, find the K nearest vectors (neighbors) in a dataset.
Example:
Dataset: 1 million vectors (documents)
Query: "domestic animal"
K = 10
Result: The 10 documents with the highest cosine similarity
Exhaustive search (brute force)
The algorithm:
1. For every vector in the dataset:
Compute similarity(query, vector)
2. Sort all the vectors by similarity
3. Return the top-K
Example with 5 vectors:
Query: [2, 3]
Vectors:
A = [2, 3] → similarity = 1.00
B = [3, 4] → similarity = 0.99
C = [1, 5] → similarity = 0.85
D = [9, 1] → similarity = 0.35
E = [0, -2] → similarity = -0.12
Top-3: A, B, C ✅
The complexity of exhaustive search
Operations per query:
- N similarity computations (N = the size of the dataset)
- Sorting N results
Complexity: O(N × d) where d = dimensionality (1536 for OpenAI)
Scalability problems:
| Dataset | Computations per query | Time (estimated) |
|---|---|---|
| 1,000 vectors | 1,000 | ~1ms ✅ |
| 100,000 | 100,000 | ~100ms ⚠️ |
| 1M | 1,000,000 | ~1s ❌ |
| 10M | 10,000,000 | ~10s ❌ |
| 100M | 100,000,000 | ~100s ❌ |
Conclusion: Exhaustive search does NOT scale to millions of vectors.
Why doesn't it scale?
Problem 1: Too many computations
With 10M vectors and 1536 dimensions:
10M × 1536 = 15.36 billion operations per query
Even on fast hardware, that takes seconds.
Problem 2: Unacceptable latency
In production:
- A search must respond in < 100ms (ideally < 50ms)
- Exhaustive search with 10M vectors → 10+ seconds ❌
The solution: Approximate search
The idea: Don't check EVERY vector. Use a smart data structure that lets you "jump" to the relevant regions of the space.
Trade-off:
- ✅ Much faster (1000x-10000x)
- ⚠️ It can miss some results (~1-5% error)
Why is that acceptable?
If the "true" top-10 is:
1. Doc A (score 0.95)
2. Doc B (score 0.94)
3. Doc C (score 0.93)
...
10. Doc J (score 0.85)
And the approximate index returns:
1. Doc A (score 0.95) ✅
2. Doc B (score 0.94) ✅
3. Doc D (score 0.92) ← Doc C was missed, but D is nearly as good
...
10. Doc K (score 0.84) ← Doc J was missed, but K is nearly as good
Users wouldn't notice the difference (Doc D is almost as good as Doc C).
Types of approximate indexes
1. HNSW (Hierarchical Navigable Small World)
- A hierarchical graph
- Very fast, ~99% precision
- More memory
2. IVF (Inverted File Index)
- Clustering + searching within clusters
- Fast, ~95-98% precision
- Less memory
3. LSH (Locality-Sensitive Hashing)
- Special hashing
- Very fast, lower precision
- Less used in modern production
You'll see each one in detail in the following capsules.
Summary
Key points:
- kNN: Finding the K nearest neighbors
- Exhaustive: O(N × d) → doesn't scale to millions
- Approximate: 1000x faster with ~1-5% error
- An acceptable trade-off: Speed > perfection for UX
Next capsule: 03-search-indexes.md — Types of indexes, comparison.