What is neighbor-ID width (32-bit vs. 64-bit)?
Neighbor-ID width is the number of bits used to store each neighbor reference in an HNSW adjacency list — most often 32-bit or 64-bit unsigned integers — which caps how many nodes the index can address and directly scales how many bytes the graph‘s edges consume.
What does a neighbor ID actually represent in the graph?
Each edge in HNSW is stored as the identifier of another node: an index into the vector store and into that node’s own metadata. A neighbor list is simply a contiguous run of those identifiers. The width of each identifier is a type choice baked into the layout: four bytes per edge for 32-bit IDs, eight bytes for 64-bit. Every node may hold up to roughly M edges on upper layers and more on the base layer, and every edge is typically stored bidirectionally, so ID width multiplies across the entire edge set. Choosing width is therefore both a capacity decision (how large N may grow) and a memory-bandwidth decision (how heavy each hop’s neighbor-list scan is).
Thirty-two bits are enough for the vast majority of single-shard HNSW deployments — and that is why they are the usual default.
When are 32-bit neighbor IDs the right choice?
A 32-bit unsigned ID addresses about 4.29 billion nodes. Few single-machine in-memory indexes approach that cardinality before RAM for vectors becomes the bottleneck: even compact 128-dimensional float32 vectors at a billion points already imply enormous DRAM, before edges are counted. For typical millions to low hundreds of millions of vectors per shard, 32-bit IDs leave huge headroom while cutting edge storage in half versus 64-bit. Scanning a neighbor list then pulls twice as many IDs per cache line, improving spatial locality on every hop. Visited sets and heap entries that store node IDs shrink too. Production layouts behind in-memory systems such as Weaviate commonly lean on compact integer IDs in this spirit so graph overhead stays proportional to M and N without wasting bytes on unused high halves of every edge word.
Sixty-four-bit IDs become relevant when addressing needs, external keys, or unified ID spaces outgrow what 32 bits can name safely.
When do you actually need 64-bit neighbor IDs?
You need them if a single index must address more than about four billion nodes, if internal IDs are sparse values drawn from a 64-bit key space rather than dense ranks, or if one process maps multiple huge segments into one addressable ID domain without renumbering. Some designs keep 64-bit external document IDs for API stability and maintain a dense 32-bit internal rank for graph edges — that hybrid preserves compact neighbor lists while still speaking 64-bit identifiers at the boundary. Blindly storing 64-bit values in every adjacency slot “for future proofing” doubles edge RAM and halves IDs per cache line even when N will never exceed a few million. Prefer dense 32-bit internal IDs plus a side map when external keys are wide; reserve 64-bit neighbor width for graphs that truly need the range inside the adjacency arrays themselves.
Width also interacts with alignment, SIMD-friendly scans, and on-disk format versioning.
What else changes in the implementation when neighbor-ID width changes?
Struct layouts, binary serializers, and mmap readers must agree on element size; mixing widths across versions without a format flag corrupts the graph on reload. Alignment of neighbor arrays follows the element size (4- or 8-byte). Some visited-set bitsets assume dense IDs in 0..N-1 and care more about density than width, but hash-based visited sets store the ID words directly and grow with width. Sorting and deduplicating neighbor lists during insertion move more bytes per comparison at 64-bit. When estimating bytes-per-vector, use (average degree × ID_width_bytes × bidirectional_factor) plus vector bytes — flipping from 32- to 64-bit can add tens of bytes per vector at typical M, which matters at hundred-million scale. Treat neighbor-ID width as a fixed index parameter chosen up front, documented in the persistence format, and changed only with a rebuild or explicit migration.
Neighbor-ID width is the bit size of each edge reference: 32-bit keeps most HNSW graphs compact and cache-friendly; 64-bit buys address range at double the edge memory. From here, the pages on neighbor lists and graph storage overhead put edges in context, bytes-per-vector memory accounting shows how to price the choice, contiguous layout and alignment cover how ID arrays should sit in memory, and the chapter on laying out HNSW’s data structures walks through concrete adjacency packing.