Awesome Open Source AI Awesome Open Source AI

Self-hosted vector databases, sized before you pick

Run pgvector if your data already lives in Postgres, Qdrant if you want one container that holds up in production, and Milvus only if you genuinely operate at hundreds of millions of vectors. The choice is less interesting than the sizing: memory is what you actually pay for in this category, so this page leads with the RAM math and the failure stories instead of a feature grid.

Updated July 12, 2026

Flat illustration of a llama weighing a large bundle of arrows on a two-pan balance scale against a few small iron weights

The short answer

You wantRun this
Vectors next to your application rows, in Postgrespgvector logo pgvector
One container that survives productionQdrant logo Qdrant
An index inside your app, no server processLanceDB logo LanceDB
A prototype running before lunchChroma logo Chroma
Hybrid search with a module ecosystemWeaviate logo Weaviate
Hundreds of millions of vectors and a platform teamMilvus logo Milvus

The RAM math

Every sizing conversation starts from the same arithmetic: a float32 embedding costs its dimension count times 4 bytes. A million 1024-dim vectors are roughly 4 GB raw; at 1536 dimensions, about 6 GB. An HNSW index and bookkeeping sit on top of that. Qdrant's capacity-planning docs multiply by 1.5 to get a planning number, and in practice the payloads and metadata stored alongside the vectors often outweigh the vectors themselves. Whatever the table below says, your metadata can double it.

DatabaseRAM per 1M vectorsCompressed / on disk
Qdrant
Official formula: vectors × dim × 4 bytes × 1.5
~6 GB at 1024-dim~0.2 GB at 1536-dim with binary quantization
Milvus
Has an official sizing tool; use it
~4–6 GB at 768-dim (HNSW)~2–4 GB with DiskANN; 60–80% savings reported with mmap
Weaviate
Docs' own rule of thumb
~2× the raw vector footprint4–7× smaller with product quantization
Chroma
No real on-disk escape hatch
~4 GB at 1024-dim (≈245k vectors per GB)Index must fit in RAM
pgvector
Index build is the hard part, not search
Reports up to ~12 GB at 1536-dim (HNSW, m=16)IVFFlat is lighter but needs periodic rebuilds

Quantization is the single biggest lever, bigger than the choice of engine. Binary quantization compresses vectors around 32×, which is how ten million 1536-dim vectors fit in roughly 2 GB of RAM on Qdrant instead of 60 GB. Scalar quantization is a gentler 4×. Recall drops slightly and you should measure it on your own queries, but for most retrieval workloads the trade is excellent.

The other lever is leaving vectors on disk and memory-mapping them. Qdrant documents a million 128-dim vectors served in about 135 MB of RAM this way. The cost shows up in throughput: on a slow disk that setup delivers well under one request per second, so mmap configurations live or die by NVMe IOPS. A cheap VPS with network-attached storage is the wrong home for one.

The engines, honestly

All six are genuinely open source with no usage restrictions on the core. The differences that matter for self-hosting are operational shape and what each does when memory runs out. Qdrant and Milvus get a full head-to-head in Qdrant vs Milvus.

Qdrant logo

The default single-container choice. Its quantization and on-disk options are what let a modest machine hold a serious collection; plan to actually use them.

Milvus logo

A distributed system, and it behaves like one: etcd, object storage, and a message queue come with it. The payoff only arrives at a scale most projects never reach.

Weaviate logo
Weaviate 16k BSD-3-Clause in the registry

Strong hybrid search and a large module ecosystem. Budget real time for version upgrades, which the project requires you to walk one release at a time.

Chroma logo

The fastest path from pip install to a working index. Teams commonly outgrow it within a year once concurrency or replication starts to matter.

pgvector logo

The right answer when Postgres already holds your data. Search is solid; building large HNSW indexes is where the pain concentrates.

LanceDB logo

An embedded, file-based store in the Arrow-compatible Lance format. Handles tens of millions of vectors with no server process to operate.

What actually breaks in production

Milvus complaints are about the entourage, not the database. A production cluster brings etcd, object storage, and a message queue, and the GitHub issues read accordingly: etcd on non-SSD volumes causing election storms and "context deadline exceeded" errors, Helm chart upgrades breaking on the Pulsar v2-to-v3 transition, teams spending their first weeks on tuning rather than search. The project knows it; in 2025 it shipped Woodpecker, a lighter write-ahead log, specifically to remove Pulsar from the stack.

Qdrant's failure mode is memory. Users report collections refusing to release RAM after large deletions, out-of-memory kills during concurrent ingestion in multi-tenant setups, and one reported case of 22 million vectors consuming over 100 GB before quantization and on-disk payloads brought it back down. File descriptor limits are the quieter surprise; raise them before the "too many open files" errors arrive.

Weaviate runs well and upgrades hard. Major-version upgrades must be walked one release at a time, a 1.19 cluster has to step through every intermediate version to reach current, and the v3-to-v4 client change forces server upgrades along with it. Moving data between self-hosted and cloud usually means re-importing rather than restoring a backup.

Chroma and pgvector fail more predictably. Chroma is a single-node design and stays honest about it; practitioner reports cluster around the six-to-twelve-month mark, when replication, access control, or concurrency needs force a migration. pgvector's pain is concentrated in one place: HNSW index builds on tens of millions of rows can overflow maintenance_work_mem, run for hours or days, and stall under lock contention while the rest of the database carries on.

When you don't need a server at all

Most teams reach for a dedicated vector database earlier than their data justifies. Under five to ten million vectors with moderate query volume, an embedded option does the job with nothing new to operate: LanceDB stores vectors in files next to your application, sqlite-vec adds brute-force search to a database you may already ship, and Faiss is the library to build on when you want an index inside your own process and don't need persistence or multi-user access.

The honest upgrade triggers are horizontal scaling, high sustained query volume, and multi-tenancy. Retrieval for a self-hosted RAG stack rarely hits any of them, which is why that guide treats the vector store as the easy part of the pipeline.

Where self-hosting beats managed on cost

The managed tiers are cheap until they aren't. Pinecone's Starter tier is free, Builder is a flat $20 a month, and Standard starts at a $50 monthly minimum with usage on top: storage at $0.33 per GB-month and read units around $16–18 per million, a meter that punishes large namespaces with heavy query traffic. Qdrant Cloud's permanent free tier (1 GB RAM, 4 GB disk) holds about a million 768-dim vectors, and paid clusters work out to roughly $57 per GB of RAM per month. Zilliz priced cold storage at $0.04 per GB-month in its January 2026 update, which is hard to beat for archival vectors.

Against that, a 16 GB droplet runs about $96 a month and, with binary quantization doing the compression, comfortably serves several million to low tens of millions of vectors. The crossover lands somewhere in the $100–500 monthly range: below it, managed convenience usually wins once you price your own time; above it, self-hosting is reported at two to seven times cheaper, and the gap widens with steady load. The number that flips the calculation back is operations. Running the database is a real fraction of an engineer, a fifth to a whole one depending on availability requirements, and that cost never shows up on the cloud bill you're comparing against.

Questions people actually ask

How much RAM does a million vectors need?

Start from the raw size: dimensions × 4 bytes per vector, so a million 1024-dim float32 embeddings are about 4 GB before any index. HNSW roughly adds half again on top (Qdrant's capacity formula multiplies by 1.5), and payloads or metadata often end up larger than the vectors themselves. Quantization changes the picture completely: binary quantization compresses vectors around 32×, which is how ten million 1536-dim vectors fit in about 2 GB.

Is pgvector enough instead of a dedicated engine?

For most workloads under ten to twenty million vectors, yes, and staying inside Postgres keeps joins, transactions, and one less service. The catch is index construction: HNSW builds on tens of millions of rows can exceed maintenance_work_mem and run for hours, and GitHub issues document out-of-memory failures on 16 GB machines. If your corpus is large and changes constantly, that build cost recurs.

Do I need a GPU?

Not for serving queries. Every engine on this page searches on CPU, and Qdrant, Weaviate, Chroma, and pgvector are CPU-first by design. Milvus can use GPUs to accelerate index building at large scale, which matters if you re-index hundreds of millions of vectors on a schedule and not otherwise.

Which one is easiest to operate day to day?

Qdrant, judging by production reports: one process, one volume, quantization built in. Chroma is even simpler to start but the simplicity runs out at scale. Milvus sits at the other extreme, since a production deployment also means operating etcd and its storage and messaging layers.

Sources

Every engine above is one row in the Awesome Open Source AI registry, under Vector Databases & Search Engines in the RAG & Knowledge category, alongside the embedding models whose dimension count sets your memory bill in the first place.

by Alvin