A 50M-vector HNSW deployment currently uses about 200 GB of RAM: 153.6 GB of raw float32 vectors (50M x 768 dims x 4 bytes) plus roughly 46.4 GB of graph links and overhead. The team upgrades to a 3072 dimension embedding model and re-embeds everything; M and the vector count stay the same, so assume graph overhead is unchanged. Predict the new total RAM footprint.
About 660 GB. Vectors scale linearly with dimension (153.6 GB to 614.4 GB), graph adjacency depends on M and N not on dimension and stays at 46.4 GB. Net growth is 3.3x, not 4x.
Picture an attic full of boxes plus the shelves they sit on. The boxes hold the actual stuff (the vectors). The shelves hold the connection diagrams (the graph). If you decide every box now needs to be four times bigger because you want to store more details inside, the boxes themselves take four times the room. But the shelves do not change shape, because there are still the same number of boxes, just bigger ones. So the attic grows, but not by a clean factor of four. It grows by however much the boxes alone got bigger, plus the unchanged shelves. The same arithmetic applies to a vector index: only the vector portion of the RAM bill scales with dimension.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Embedding dimension upgrades are one of the most common capacity-planning exercises a vector database team does. The mistake teams make again and again is treating the upgrade as a single multiplier on the old memory bill, when in fact only some components of the bill scale with dimension. Getting this right is a matter of decomposing the bill into structural pieces and asking which pieces depend on the parameter you changed.
The rest of this section walks through the arithmetic, the why behind each term, and the operational decisions that surround a dimension upgrade. The exact same framing applies to upgrades within an embedding family (768 to 1536 to 3072), to switches across providers, and to changes in dtype (float32 to int8 to binary), as long as you know which structural piece each parameter governs.
Decomposing the memory bill
Every HNSW deployment's RAM footprint breaks into four structural components.
Raw vectors. This is the bulk array of float32 (or float16, or quantized) values. Size is . Linear in N, linear in d, linear in dtype width. In the question, 50M x 768 x 4 = 153.6 GB.
Graph adjacency. HNSW maintains a layered graph. Each node at the base layer has up to M outgoing edges; upper-layer nodes appear with probability roughly $1/2^{\ell}M/2 edges. Across about log(N) layers, the per-node adjacency cost is roughly \2 \cdot M \cdot \text{sizeof}(\text{node_id})$. For M=16 and 8-byte IDs, that is 256 bytes per node, times 50M nodes is 12.8 GB. The 46.4 GB in the question is graph plus engine overhead, which is consistent with M in the 16 to 32 range plus a chunk of engine bookkeeping.
Engine overhead. Segment headers, allocator slop, deletion bitmaps, payload index, ID-to-offset mappings. Typically 5 to 15 percent of vectors plus graph.
Operational headroom. Free space for ingest, compaction temporaries, replication buffer. 10 to 30 percent on top.
The question lumps the last three into one number (46.4 GB), which is fine for this exercise. The point is that each term depends on a different set of parameters, and changing one parameter only multiplies the terms that depend on it.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
Real products, models, and research that use this idea.
- OpenAI text-embedding-3-large is 3072 dims; teams upgrading from text-embedding-ada-002 (1536) routinely budget the doubling incorrectly because graph and overhead are not on the linear-in-d term
- Pinecone serverless capacity calculators distinguish vector bytes from index overhead specifically so customers do not multiply the whole bill
What an interviewer would ask next. Try answering before peeking at the approach.
QIf you also doubled M to compensate for higher dimension noise, what happens to the bill?
Graph bytes scale linearly with M, so doubling M roughly doubles the 46.4 GB graph term to about 93 GB. Total becomes 614.4 + 93 = 707 GB. M is the lever for graph cost; d is the lever for vector cost.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Multiplying the whole 200 GB by 4x and getting 800 GB, or ignoring the graph entirely and getting 614 GB. Both miss the structural split between vector bytes and graph bytes.
60 second bullets to scan on the way to the call.
How to split a vector index memory bill into vector bytes, graph adjacency, engine overhead, and headroom
Which terms scale with dimension and which scale with N or M
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.