What is peak build memory?
Peak build memory is the highest amount of RAM an HNSW index construction process occupies while the graph is being created — usually higher than the finished index — because insertion temporarily holds candidate lists, scratch buffers, and per-thread state on top of the partially built graph.
Why is building the graph hungrier than serving queries from the finished index?
Every insertion runs a construction search controlled by efConstruction, which maintains candidate and result structures that can hold hundreds of node IDs and distances at once. Neighbor selection may keep an extended candidate set before pruning down to M edges. Multithreaded builds multiply those scratch structures by the worker count and add allocator contention overhead. The graph itself is also growing throughout the run, so late insertions sit on nearly full vector and edge storage while still allocating temporary search state. When the build finishes, candidate heaps and many temporaries are released, and RSS often drops toward steady-state memory — which is why sizing a machine only to the final index size is a classic way to OOM halfway through ingest.
Several knobs and design choices move that peak in predictable directions.
What drives peak build memory up or down in practice?
Higher efConstruction is the clearest algorithmic driver: larger candidate lists per insertion mean more bytes per worker for the whole build. More build threads raise aggregate scratch even when each thread’s peak is similar. Larger M increases both final edge storage (which is already present late in the build) and temporary neighbor buffers. Batching strategies that stage large pending-edge lists before commit can spike memory further. Holding both full-precision and quantized vectors during a compressed build doubles the vector bucket until one copy is discarded. Contiguous arenas tend to show cleaner peaks than per-node malloc forests, which add allocator overhead on top of logical sizes. In-memory systems that index under load, including deployments like Weaviate, often recommend sizing for ingest separately from query capacity for exactly these reasons.
Measuring the peak matters as much as estimating it, because fragmentation and runtime extras rarely appear in napkin math.
How should you measure peak build memory for an HNSW job?
Sample RSS or the container’s memory working set throughout the build — not only at the end — and record the maximum. Note thread count, efConstruction, M, dimensionality, N, and whether other query traffic ran concurrently. Compare that peak to the post-build steady-state footprint to learn the build overhead ratio for your implementation. If the process runs under a cgroup or orchestrator limit, set the limit above the measured peak with headroom for the OS page cache if vectors are read from files during ingest. A single end-of-run reading of “final index size” will not catch the mid-build crest where large efConstruction heaps and a nearly complete graph coexist.
When peak build memory is the constraint, you tune the build profile — not only the finished graph’s recall.
How do you reduce peak build memory without abandoning HNSW quality goals?
Lower efConstruction until recall at your target efSearch still meets the bar after a validation pass; build quality often saturates before the highest efConstruction values. Cap build concurrency to what memory allows even if more cores sit idle. Build in shards so each process’s peak covers only a fraction of N, then serve or merge according to your architecture. Avoid retaining duplicate vector representations longer than needed. Release large temporary buffers explicitly between phases if the allocator does not return memory to the OS promptly. Prefer streaming insertion from disk over loading all raw vectors into RAM beside the growing index when the dataset is huge. Peak build memory is a first-class capacity metric beside bytes-per-vector of the finished graph — plan for both, or the build becomes the outage.
Peak build memory is the high-water mark during HNSW construction, driven by efConstruction scratch, threads, and a growing graph — and it is what you must size machines for, not only the final RSS. From here, the steady-state memory page covers the post-build footprint, bytes-per-vector accounting shows how to estimate the finished index, efConstruction explains the main algorithmic lever, and the chapter on concurrent HNSW construction discusses how thread count trades build speed for peak RAM.