What a vector database costs to hold. The driver is vector count multiplied by dimensions, and vector count is where the surprises live: a small corpus chunked finely at 3,072 dimensions lands where a large one summarised at 384 does, and a late-interaction model storing one vector per image patch lands two orders of magnitude above both.
Estimated at 1.33 tokens per word. Length spread across documents does not change the answer, except where documents are shorter than one chunk.
Overlap raises the vector count and duplicates stored text, so the payload exceeds the size of the original corpus.
A thumbnail or rendered page held next to the vectors. Originals usually stay in object storage and are not counted here.
Models trained with Matryoshka representation can be truncated to a shorter prefix with limited accuracy loss.
Vectors Index Payload Metadata
| Component | Size |
|---|---|
| Vector data | -- |
| Index structure | -- |
| Payload | -- |
| Metadata and ids | -- |
| Total | -- |
The graph is traversed on every query, so it stays in memory whatever the vectors do. Quantising to int8 shrinks the vectors and leaves the graph untouched, which is why the saving is smaller than the ratio suggests at low dimensions.
Total on disk for the current vector count, holding everything else fixed. Truncating a Matryoshka model from 1,536 to 384 dimensions moves you three rows up this table.
| Dimensions | float32 | float16 | int8 | binary |
|---|---|---|---|---|
| 384 | -- | -- | -- | -- |
| 768 | -- | -- | -- | -- |
| 1024 | -- | -- | -- | -- |
| 1536 | -- | -- | -- | -- |
| 3072 | -- | -- | -- | -- |
| 4096 | -- | -- | -- | -- |
Vector count and total at the current dimensions and precision. Halving the chunk size roughly doubles everything.
| Chunk size | Vectors | Vector data | Total on disk |
|---|---|---|---|
| 128 tokens | -- | -- | -- |
| 256 tokens | -- | -- | -- |
| 512 tokens | -- | -- | -- |
| 1024 tokens | -- | -- | -- |
| 2048 tokens | -- | -- | -- |
Everything reduces to vector count multiplied by dimensions. For text, vectors per item is the number of chunks a document produces; for images it is one, unless the model keeps a vector per patch or per token:
chunks_per_doc = max(1, ceil((doc_tokens - overlap) / (chunk_size - overlap)))
vector_count = items × vectors_per_item
vector_bytes = vector_count × dimensions × precision_bytes
The max(1, ...) matters more than it looks. A corpus of 200,000 support
tickets at 40 tokens each still produces 200,000 vectors, not the 17,000 a
divide-the-total estimate returns.
HNSW adds a navigable graph. Layer zero holds twice M bidirectional links per node and the upper layers add roughly 15% more, stored as 32-bit ids. IVF stores centroids plus a list assignment per vector, with the list count sized at the square root of the vector count. Flat indexes add nothing beyond the vectors:
hnsw_bytes = vector_count × 2M × 4 × 1.15
Metadata is charged per stored row. Single-vector models write one row per vector; late-interaction models normally hold their patch vectors as an array on one row per item, so metadata is charged per item there instead.
Text payload is estimated at four bytes per token, which holds for English in UTF-8. Because overlapping chunks duplicate their shared tokens, stored text exceeds the corpus by roughly the ratio of chunk size to stride.
Background: why vector databases are difficult, data methods for RAG, event-driven embeddings in PostgreSQL, and model choice and VLM inference cost. Related: the inference VRAM calculator. (If you are sizing this against a real corpus, get in touch.)