datarekha
Infrastructure June 12, 2026

The vector-search memory wall: why HNSW eats RAM, and how quantization cuts the bill 32×

HNSW is fast because the whole graph lives in RAM — which is exactly why it gets expensive. At 100M vectors you're paying for ~600GB of memory before you serve a single query. Here's the math, and how binary quantization plus reranking is rewriting the cost model in 2026.

11 min read · by datarekha · vector-dbhnswquantizationbinary-quantizationrag

Vector search has a dirty secret, and it shows up on the invoice. The thing that makes HNSW fast — keeping a navigable graph of your vectors resident in memory — is the same thing that makes it expensive. You are not paying for compute. You are paying for RAM, and you are paying for it before a single query arrives.

This is the part most “just add a vector database” tutorials skip. So let’s do the math, then look at how the 2026 vector stack is quietly demolishing the memory bill.

Why HNSW lives in RAM

A quick recap of the mechanism (the full version is in the vector databases lesson). HNSW — Hierarchical Navigable Small World — builds a layered graph over your vectors. A query enters at the top layer, greedily hops toward the nearest neighbor, drops a layer when it can’t get closer, and refines on the dense bottom layer. A few dozen hops replace a brute-force scan of every vector.

But every one of those hops does the same two things: follow a graph edge, and compute a distance. Follow an edge means random memory access — the next node could be anywhere in the index. Compute a distance means reading a high-dimensional vector and doing 1,536 multiply-adds. Do that across 30–50 hops per query, thousands of queries per second, and the access pattern is pathologically random and latency-sensitive.

That pattern only works at memory speed. The moment the graph or the vectors spill to disk — even a fast NVMe SSD — each random read costs tens of microseconds instead of tens of nanoseconds, and a query that took 2ms in RAM takes hundreds of milliseconds or seconds off disk. There is no graceful degradation. You are either in memory or you are slow.

The bill, in bytes

Here is where it gets uncomfortable. Take a realistic production index: 100 million chunks, embedded at 1,536 dimensions (OpenAI text-embedding-3 size), stored as 32-bit floats.

vectors:  100,000,000 × 1,536 dims × 4 bytes  =  614 GB
HNSW graph (M=16 neighbors, ~8 bytes each, +upper layers)  ≈  20 GB
                                               ────────────
                                       total  ≈  ~634 GB resident

Six hundred gigabytes of RAM, held hot, around the clock, just to hold the index — before you account for query traffic, replicas for availability, or headroom. On managed infrastructure a 100M-vector index runs on the order of $6,000 a month, and most of that line item is memory you provisioned so the graph never touches disk.

Double your corpus and you double the bill. This is the wall every team hits somewhere between 10M and 100M vectors: the algorithm still works beautifully, but the unit economics stop making sense.

The escape hatch: store smaller, search smaller

The fix is not a cleverer graph. It’s storing each vector in fewer bits. Embeddings are remarkably tolerant of precision loss — the geometry that makes two vectors “close” survives a surprising amount of rounding. Quantization exploits exactly that.

RAM FOR 100M × 1536-DIM VECTORSfloat32614 GB32 bits / dimfloat16307 GB16 bits / dim • −50%int8154 GB8 bits / dim • −75%binary19 GB1 bit / dim • −97% (32×)Same 100M vectors, fewer bits each. Binary is the difference between a $6k server and a $400 one.

The ladder is steep:

  • float16 halves memory by dropping to 16-bit floats. Nearly free in accuracy; the most conservative win.
  • int8 maps each dimension to one of 256 buckets — a 4× cut. The catch is calibration: naive min-max scaling breaks when a few outlier dimensions stretch the range, so good implementations fit the buckets per-dimension on a data sample.
  • binary is the dramatic one. Keep a single bit per dimension — is this component above the mean or below it? A 1,536-dim vector collapses from 6,144 bytes to 192 bytes, a 32× reduction. And the distance computation becomes a Hamming distance: XOR two bit-strings and count the ones, an operation modern CPUs do absurdly fast. Qdrant measured binary quantization at up to 40× faster search.

”But binary throws away almost everything”

It does. One bit per dimension is a savage approximation, and on its own it tanks recall — you’ll find the right neighborhood but rank the wrong vector first. The trick that makes it production-grade is to not trust the compressed index for the final answer.

The pattern is oversample and rerank:

  1. Search the compressed index (in RAM, blazing fast) but ask for more candidates than you need — if you want the top 10, retrieve 30 or 40.
  2. Pull the full-precision vectors for just those ~40 candidates from disk (cheap — it’s 40 reads, not 100 million).
  3. Rescore the candidates with the exact distance and return the true top 10.

You do the expensive, accurate math on a tiny shortlist, and the cheap, approximate math on the whole corpus. Recall climbs back to 95–99% while the hot, always-resident part of the index stays 32× smaller.

The oversampling factor is the dial. Elasticsearch’s Better Binary Quantization (BBQ) reports high recall with inner-product similarity at only ~3× oversampling, and it composes with HNSW directly. Qdrant recommends binary quantization only with rescoring enabled, for the same reason. Research indexes are pushing further: density-aware adaptive quantization has demonstrated 4× compression at 98%+ recall while running 2.5–3.3× more queries per second than a standard HNSW build.

The other lever: shorter vectors, not just smaller numbers

Quantization shrinks each number. Matryoshka embeddings shrink the count of numbers. Models trained with Matryoshka Representation Learning pack the most important information into the leading dimensions, so you can truncate a 1,536-dim vector to 512 or 256 dims and keep most of the signal. Stack that with int8 quantization and teams have reported ~80% cost reductions with single-digit recall loss. The two techniques are orthogonal — fewer dimensions and fewer bits per dimension multiply.

What to actually do

A pragmatic ladder, cheapest decision first:

  • Under ~5M vectors: don’t optimize. Plain HNSW in pgvector fits in RAM and costs nothing extra. (We made the broader “which database” case in the vector DB shakeout.)
  • 5M–50M: turn on int8 / scalar quantization with rescoring. It’s the free lunch — 4× less memory, negligible recall loss, supported everywhere.
  • 50M+ or latency-and-cost-bound: go binary quantization with oversampling + rerank, and look hard at Matryoshka truncation on top. This is where the order-of-magnitude savings live.
  • Always: measure recall on your queries before and after. Quantization is a recall-for-memory trade, and the right oversampling factor is empirical, not a default.

The headline for 2026 is simple. Vector search stopped being a question of “which algorithm” — HNSW won that — and became a question of “how few bits can you get away with.” The teams winning on cost aren’t running a different index. They’re running the same index, 32 times smaller, and doing the precise math only where it counts.


Keep going: the vector databases lesson covers how HNSW navigates in the first place (with an interactive layer-by-layer explorer), and hybrid search at scale covers what to pair it with when pure vector search isn’t enough.

Skip to content