← Back to Technical Library

Vector Database Comparison for Sovereign RAG

A comprehensive, deep technical comparison of every self-hostable vector database for on-premise RAG. Qdrant, pgvector, Chroma, Weaviate, Milvus, LanceDB, FAISS, Redis, Elasticsearch, Vespa, and Vald -- with a massive comparison table, decision guide, and Docker deployment notes for each. Cloud-only options like Pinecone are covered only to explain why to avoid them.

Qdrant (Recommended) pgvector Chroma Weaviate Milvus LanceDB FAISS Redis Vector Elasticsearch Vespa Vald Pinecone (Cloud-only)

Why This Comparison Is Sovereign-Only

The vector database is the heart of any RAG system. It stores the embeddings of your documents, and at query time it performs approximate nearest neighbor (ANN) search to find the chunks most relevant to a user's question. In a sovereign, on-premise RAG deployment, the vector database holds the embeddings of your most sensitive data -- medical records, legal contracts, proprietary source code, internal communications, financial filings -- and the choice of database determines not just performance but whether your data ever leaves your network.

This page covers every vector database that you can run on hardware you control. We exclude cloud-only services except to explain why they are incompatible with sovereign RAG. A cloud vector database like Pinecone stores your embeddings on someone else's servers, accessed through someone else's API, governed by someone else's terms of service. Even though embeddings are not raw text, they are reversible: a sufficiently motivated attacker with access to the embedding model can invert embeddings to recover approximate source text. For HIPAA-regulated medical records, attorney-client-privileged legal documents, and proprietary business data, the vector database must run on your hardware, under your access controls, with audit logs you own.

The Sovereign Vector Database Principle: The vector database that stores embeddings of your data must run on hardware you control, be deployed from source or a self-hosted Docker image you can audit, never transmit embeddings or metadata to a third-party API, and be governed by your access policies and audit infrastructure. A cloud-hosted vector database violates this principle regardless of its SOC 2 or HIPAA certifications, because the operator can access your embeddings and is bound by their policies, not yours.

What We Compare

For each database, we cover: the implementation language (which affects deployment weight and performance characteristics), the license (which affects whether you can use it commercially and whether it can be locked down), the API style (REST, gRPC, GraphQL, SQL), the indexing algorithm (HNSW, IVFFlat, IVF-PQ, NGT), the maximum scale (thousands, millions, or billions of vectors), multi-modal support (whether it can store image, audio, and video embeddings alongside text), persistence model (on-disk, in-memory, embedded file), distributed mode support, payload filtering (metadata filtering alongside vector search), and the specific scenarios where each database is the best choice. We then provide a master comparison table, a feature matrix, a decision guide keyed to use case, Docker deployment notes for each, and a resource-requirements table covering RAM, CPU, disk, and GPU needs.

How to Read This Page: If you know your use case, skip to the Decision Guide. If you want the full picture at a glance, go to the Master Comparison Table. If you want to deploy one today, go to the Docker Deployment Notes. If you want to understand why we recommend Qdrant, read the next section in full.

Qdrant — Our Primary Recommendation

pgvector — PostgreSQL Extension

pgvector

PostgreSQL Extension C PostgreSQL License SQL

pgvector is not a standalone database -- it is an extension to PostgreSQL that adds vector types and vector similarity search. This is its defining advantage and its defining limitation. The advantage: if you already run PostgreSQL, you add vector search with CREATE EXTENSION vector and you have a vector database. No new database to deploy, no new query language to learn, no new backup strategy, no new monitoring tool. Your existing Postgres DBA, your existing pg_dump backups, your existing replication setup, and your existing SQL queries all work with vectors as first-class citizens.

pgvector supports two index types. HNSW (Hierarchical Navigable Small World) is the default for most workloads: it builds a graph index that gives fast approximate search with tunable recall via the ef_search parameter. HNSW is the same algorithm Qdrant and many others use. IVFFlat (Inverted File with Flat quantization) is the older alternative: it partitions vectors into clusters and searches only the most relevant clusters. IVFFlat builds faster but has lower recall at high speeds than HNSW. For most sovereign RAG deployments, HNSW is the right choice.

When to Choose pgvector Over Qdrant

Two scenarios pull you toward pgvector. First: you need ACID transactions that include vector operations. If you want to insert a document, insert its chunks, insert their embeddings, and update a metadata table, all in one atomic transaction that either commits entirely or rolls back entirely, pgvector is the only option in this comparison that does that natively. Qdrant has no transactions across collections; neither does Chroma, Milvus, or Weaviate. For a medical records system where you must guarantee that a patient's record and its embeddings are written atomically, pgvector is the correct choice.

Second: you already have PostgreSQL infrastructure. If your application already runs on Postgres, adding a separate Qdrant container means a new database to monitor, back up, secure, and scale. If your vector count is under 10 million, pgvector with HNSW will perform well enough that the operational simplicity of one database outweighs Qdrant's raw speed advantage. For teams without a dedicated DBA or DevOps engineer, running one database instead of two is a significant reduction in operational risk.

Scale Limit: pgvector's practical ceiling is around 10 million vectors per table before HNSW build times and memory usage become painful. Beyond that, a dedicated vector database (Qdrant, Milvus) is more efficient. If you expect to exceed 10M vectors, plan for a migration or choose a dedicated database from the start.
Strengths
  • SQL-native -- no new query language
  • ACID transactions with vectors (unique in this comparison)
  • No new database to deploy (if you already run Postgres)
  • Reuses Postgres backups, replication, monitoring, access control
  • HNSW + IVFFlat index support
  • PostgreSQL License (permissive, similar to MIT/BSD)
  • Combines with pg_trgm, pg_bm25, or zhparser for hybrid search in one DB
  • Join vectors with relational data in the same query
Limitations
  • Practical ceiling ~10M vectors per table
  • HNSW index build is slow for large tables (hours)
  • Higher memory usage than Qdrant at scale (Postgres overhead)
  • No built-in quantization (vectors stored at full precision by default)
  • No distributed mode (sharding requires Citus or manual partitioning)
  • Requires PostgreSQL 13+ and the extension installed on the server
  • Slower search than Qdrant at equivalent recall (Postgres query overhead)
# pgvector -- install the extension on an existing Postgres docker run -d \ --name pgvector \ -p 5432:5432 \ -e POSTGRES_PASSWORD=changeme \ -e POSTGRES_DB=ragdb \ -v /opt/pgvector/data:/var/lib/postgresql/data \ --restart unless-stopped \ pgvector/pgvector:pg16 # Then in SQL: CREATE EXTENSION vector; CREATE TABLE chunks ( id bigserial PRIMARY KEY, content text, embedding vector(1024), source text, page int ); CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);

Chroma — Python-Native, Lightweight

Chroma (ChromaDB)

Python Apache 2.0 DuckDB-based REST + Python SDK

Chroma is the easiest vector database to start with. It is Python-native, ships as a pip install (pip install chromadb), and runs in-process or as a small server. Under the hood, it uses DuckDB as its storage and query engine -- DuckDB is an embedded analytical database (like SQLite for analytics), which means Chroma has no external dependencies, no separate server process required for single-node use, and no network configuration for local development.

This makes Chroma the ideal prototyping database. If you are building a proof-of-concept RAG system, testing chunking strategies, or developing an embedding-model evaluation pipeline, Chroma lets you go from pip install to storing and retrieving vectors in under five minutes. The Python SDK is clean and intuitive: collection.add(documents=[...], embeddings=[...], metadatas=[...]) and collection.query(query_embeddings=[...], n_results=5). No Docker, no YAML, no server config.

The trade-off is scale and performance. Chroma is not designed for production workloads at millions of vectors. DuckDB is an in-process analytical engine, not a high-concurrency transactional server. Chroma's server mode exists and works, but it does not have the distributed mode, the quantization, or the payload filtering sophistication of Qdrant. For a personal AI assistant with 50,000 chunks, Chroma is perfectly adequate. For a medical practice with 5 million patient-document chunks and 50 concurrent clinicians querying it, Chroma will struggle.

When to Use Chroma

  • Quick prototypes and proof-of-concept RAG systems
  • Small datasets (under ~500K vectors)
  • Development environments where you want zero infrastructure
  • Embedding-model evaluation pipelines (fast iteration)
  • Single-user personal AI assistants with modest collections
  • Notebooks and tutorials (Chroma is the default in many LangChain tutorials)
Strengths
  • Easiest setup of any database in this comparison
  • Python-native, pip install, in-process mode
  • No external dependencies (DuckDB is embedded)
  • Apache 2.0 license
  • Clean Python SDK, popular in the LangChain ecosystem
  • Server mode available for small-team deployments
  • Good for prototyping and evaluation pipelines
Limitations
  • Not designed for production scale (millions of vectors)
  • No distributed mode (no sharding, no replication)
  • No built-in quantization
  • DuckDB is analytical, not high-concurrency OLTP
  • Slower search than Qdrant or pgvector at scale
  • Limited payload filtering (basic where-clauses only)
  • Smaller production track record than Qdrant or Milvus
# Chroma -- in-process (no server needed for prototyping) pip install chromadb # Python: import chromadb client = chromadb.PersistentClient(path="/opt/chroma/data") collection = client.create_collection(name="rag_docs") collection.add(documents=[...], metadatas=[...], ids=[...]) results = collection.query(query_texts=["question"], n_results=5) # Chroma server mode (for small-team access): docker run -d --name chroma -p 8000:8000 \ -v /opt/chroma/data:/chroma/chroma --restart unless-stopped \ chromadb/chroma

Weaviate — GraphQL, Multi-Modal, Module System

Weaviate

Go BSD-3-Clause GraphQL + REST

Weaviate is a Go-based vector database distinguished by two features: a GraphQL API and a module system. The GraphQL API lets you query vectors and their metadata through typed GraphQL schemas, which is more expressive than REST for complex queries ("find documents about cardiology, return their text and their source file, filter by date range and department, limit to 10 results"). The module system is Weaviate's answer to the "you bring your own embedding model" problem: Weaviate can automatically call a configured embedding model (text2vec, text2vec-contextionary, multi2vec, image2vec) when you insert text or images, so you can insert raw documents and let Weaviate handle embedding.

For sovereign RAG, the module system is a double-edged sword. The convenience of inserting raw text and letting Weaviate embed it is appealing, but the default modules call cloud embedding APIs (OpenAI, Cohere). To keep embeddings on-premise, you must configure the modules to call a local embedding service (a local sentence-transformers model served via TorchServe, vLLM, or a custom HTTP endpoint). This is entirely possible -- Weaviate supports custom modules and local model servers -- but it requires more configuration than Qdrant, where you embed with your own model and insert the vectors directly.

Weaviate's multi-modal support is its strongest differentiator. The multi2vec module can store text and image vectors in the same collection and perform cross-modal search ("find images similar to this text description"). For a multi-modal RAG system that retrieves across text, images, and potentially audio, Weaviate is a strong contender. However, as the multi-modal RAG page explains, you can achieve the same thing with Qdrant by storing text and image vectors in the same collection with a modality field in the payload. The difference is that Weaviate has built-in support for the workflow, while Qdrant requires you to build it yourself.

When to Choose Weaviate

  • Multi-modal RAG where you want built-in cross-modal search
  • Teams that prefer GraphQL over REST for complex queries
  • Use cases where automatic embedding (via configured modules) is preferred over bring-your-own-vectors
  • Applications needing Weaviate's built-in question-answering and summarization modules
Strengths
  • GraphQL API (expressive for complex queries)
  • Module system (extensible, can plug in local embedding models)
  • Multi-modal support (text + image in same collection)
  • BSD-3-Clause license (permissive)
  • Built-in hybrid search (BM25 + vector in one query)
  • Go-based (good performance, single binary deployment)
  • Good documentation and active community
Limitations
  • Module system defaults to cloud embedding APIs (must configure for sovereignty)
  • Heavier than Qdrant (Go runtime, more moving parts)
  • GraphQL is a learning curve if your team knows REST/SQL
  • Slower raw vector search than Qdrant (Go GC pauses under load)
  • Less mature distributed mode than Milvus
  • More complex Docker setup (multiple containers for modules)
# Weaviate -- standalone (no modules, bring your own embeddings) docker run -d --name weaviate \ -p 8080:8080 \ -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \ -e PERSISTENCE_DATA_PATH=/var/lib/weaviate \ -v /opt/weaviate/data:/var/lib/weaviate \ --restart unless-stopped \ semitechnologies/weaviate:latest # For multi-modal with local embedding, use docker-compose with # a custom module config pointing to your local embedding server. # See Weaviate docs for module configuration. No GPU required for the # database itself; the embedding server may need GPU depending on model.

Milvus — Billion-Scale, Distributed

Milvus

C++ / Go Apache 2.0 gRPC + REST

Milvus is the heavyweight of this comparison, in the literal sense. It is a C++ and Go-based vector database designed for billion-scale vectors across distributed clusters. If Qdrant is the lightweight single-node champion, Milvus is the distributed-systems champion. It was built by Zilliz (originally at Zilliz Cloud, now an independent open-source project under the LF AI & Data Foundation) specifically for the use case where you have 100 million to 10 billion vectors and need to search them across a cluster of machines.

Milvus supports multiple index types -- IVF_FLAT, IVF_PQ, IVF_SQ8, HNSW, ANNOY, DISKANN, and several GPU-accelerated indexes (GPU_IVF_FLAT, GPU_IVF_PQ, GPU_CAGRA). The GPU-accelerated indexes are Milvus's standout feature: if you have NVIDIA GPUs available, Milvus can use them for both indexing and search, achieving 10x+ throughput over CPU-only databases on large collections. For a sovereign deployment with a GPU-equipped server (which you likely already have for running the LLM), Milvus can repurpose that GPU for vector search during idle LLM time.

The cost of this power is operational complexity. A production Milvus deployment is not a single container. It requires Milvus itself plus etcd (configuration storage), MinIO or S3 (object storage for vector data), and Pulsar or Kafka (message queue for write operations). A standalone mode exists (single container with embedded dependencies) for development, but production deployments use the distributed mode with separate services. This is the right choice for an enterprise that already operates Kubernetes and has a DevOps team, and the wrong choice for a medical practice deploying RAG on a single server.

When to Choose Milvus

  • Enterprise deployments with 100M+ vectors
  • Use cases requiring GPU-accelerated vector search
  • Organizations with Kubernetes infrastructure and DevOps capacity
  • High-throughput ingestion (millions of vectors per hour)
  • When horizontal scaling across multiple nodes is a hard requirement
Strengths
  • Designed for billion-scale vectors
  • GPU-accelerated indexes (GPU_IVF, GPU_CAGRA)
  • Mature distributed mode (sharding, replication, failover)
  • Multiple index types (HNSW, IVF, DiskANN, GPU indexes)
  • Apache 2.0 license
  • C++ core for maximum search speed
  • Strong ecosystem (Attu GUI, integration with many frameworks)
  • LF AI Foundation governance (vendor-neutral)
Limitations
  • Most operationally complex database in this comparison
  • Production deployment requires etcd + MinIO + Pulsar + Milvus
  • Standalone mode is for development only (not production)
  • Heavy resource footprint (RAM, CPU, disk for all services)
  • Kubernetes recommended for production (steep learning curve)
  • Overkill for collections under 10M vectors
  • More moving parts = more failure modes
# Milvus standalone (development only): docker run -d --name milvus-standalone \ -p 19530:19530 -p 9091:9091 \ -v /opt/milvus/data:/var/lib/milvus \ --restart unless-stopped \ milvusdb/milvus:latest standalone # Production: use docker-compose or Helm chart with: # - milvus (the database itself) # - etcd (config storage) # - minio (object storage for vectors) # - pulsar or kafka (write-ahead message queue) # GPU optional for GPU-accelerated indexes. CPU-only works for HNSW/IVF.

LanceDB — Embedded, No Server, Columnar

LanceDB

Embedded Rust Apache 2.0 Python + Rust SDK

LanceDB is the SQLite of vector databases. It is an embedded database -- no server process, no network port, no Docker container. You open a LanceDB database by pointing it at a directory on the filesystem, and you read and write vectors through a Python or Rust SDK. The data is stored in Lance format, a columnar format designed for machine learning workloads (like Parquet but optimized for random access and vector search). Under the hood, LanceDB uses a Rust core with an IVF-PQ index built on the Lance format.

This makes LanceDB the right choice for edge devices, single-user systems, and embedded RAG applications where you cannot or do not want to run a server. If you are building a personal AI assistant that runs on a laptop or a Raspberry Pi, LanceDB lets you store and search vectors without a database server. If you are building an embedded AI feature in a desktop application (a code search tool, a local document search app), LanceDB is the database that fits -- no server to install, no port to configure, no process to manage.

The Lance format is also notable: it is a columnar format, which means you can store vectors alongside structured metadata, images (as binary blobs or file paths), and text in the same table, and query any column without loading the others. For multi-modal RAG on resource- constrained devices, this is a meaningful advantage. LanceDB also supports disk-based indexes, so you can search collections larger than RAM without a server.

When to Choose LanceDB

  • Edge devices and embedded systems (no server process possible)
  • Single-user personal AI assistants running on a laptop or mini-PC
  • Desktop applications with built-in RAG (code search, document search)
  • Use cases where no server process can be run (IoT, kiosk, offline device)
  • Prototyping where you want the simplicity of Chroma with better performance
  • Columnar storage is a requirement (ML feature stores, multi-modal data)
Strengths
  • Embedded -- no server, no Docker, no network
  • SQLite-like simplicity (open a directory, read/write vectors)
  • Rust core (fast, low memory, no GC)
  • Apache 2.0 license
  • Columnar Lance format (efficient for ML workloads)
  • Disk-based IVF-PQ index (search larger-than-RAM collections)
  • Multi-modal (vectors, images, text, metadata in one table)
  • Zero-configuration deployment
Limitations
  • No server mode = no concurrent multi-user access
  • No distributed mode (single-node only)
  • Smaller community than Qdrant or Milvus
  • Newer project (less battle-tested in production)
  • No built-in full-text search (bring your own BM25)
  • IVF-PQ only (no HNSW -- different recall/speed tradeoff)
  • Python SDK is primary; Rust SDK is less mature
# LanceDB -- no Docker. No server. Just pip install. pip install lancedb # Python: import lancedb db = lancedb.connect("/opt/lancedb/my_db") # Just a directory db.create_table("rag_docs", data=[ {"vector": [0.1, 0.2, ...], "text": "chunk text", "source": "file.pdf"} ]) results = (db.open_table("rag_docs") .search([0.1, 0.2, ...]) .limit(5) .to_list()) # No GPU required. Disk-based index. Runs on anything.

FAISS — Library, Not a Database

FAISS (Facebook AI Similarity Search)

C++ / Python MIT Library (no API)

FAISS is not a database. It is a C++ library (with Python bindings) for dense vector similarity search, developed by Facebook AI Research. It is the fastest pure vector search library in this comparison -- possibly the fastest in existence. FAISS implements every major ANN algorithm (IVF, IVF-PQ, HNSW, and GPU-accelerated variants) and is the algorithmic foundation that several other databases build on or benchmark against.

But FAISS has no CRUD operations, no persistence layer, no API server, no authentication, no metadata filtering, no replication, and no distributed mode. You load vectors into a FAISS index in memory, search them, and save/load the index to/from a file. If you want to add a vector, you rebuild the index (or use an incremental index type, which has limitations). If you want to delete a vector, you rebuild the index. If you want to filter by metadata, you do it yourself in Python after FAISS returns results. If you want the index to survive a process restart, you write code to serialize and deserialize it.

This means FAISS is the right choice when you want to build your own vector database. If you have a custom system with specific requirements that no existing database meets -- unusual index types, extreme performance requirements, integration with a custom storage layer -- you build it on FAISS. FAISS gives you the search engine; you build the database around it (persistence, CRUD, API, metadata, auth). This is the most work but gives you the most control.

For most sovereign RAG deployments, this is the wrong choice. The work of building a database around FAISS (persistence, concurrent access, metadata, backups, API) is exactly the work that Qdrant, pgvector, and Milvus have already done. Choose FAISS only when you have a specific need that requires custom engineering and you have the engineering capacity to build and maintain a database layer.

When to Choose FAISS

  • Custom systems where you need maximum control over the search engine
  • Research projects where you are experimenting with novel index types
  • Embedded use where FAISS is wrapped in a larger application (not exposed as a database)
  • Batch processing pipelines (index once, search many, no updates)
  • When you need GPU-accelerated search and want to manage it yourself
  • As a building block -- many other databases use FAISS internally
Strengths
  • Fastest pure vector search (C++ core, optimized algorithms)
  • Every major ANN algorithm (IVF, IVF-PQ, HNSW, GPU variants)
  • GPU-accelerated search (best GPU support in this comparison)
  • MIT license (most permissive possible)
  • Mature, battle-tested (developed by Meta AI Research)
  • Python bindings (numpy arrays in, numpy arrays out)
  • Foundation that other databases build on
Limitations
  • Not a database -- no CRUD, no persistence, no API
  • You must build your own database layer (significant engineering)
  • No metadata filtering (do it yourself, post-search)
  • No concurrent access (single process, manage locking yourself)
  • No replication or distributed mode (build it yourself)
  • No authentication, no audit logging (add it yourself)
  • Index updates require rebuild for non-incremental types
  • Steepest implementation curve of any option here
# FAISS -- no Docker. It's a library. pip install faiss-cpu # or faiss-gpu for GPU support # Python: import faiss import numpy as np index = faiss.IndexFlatIP(1024) # inner product (cosine if normalized) index.add(vectors_np_array) # in-memory only distances, ids = index.search(query_vector, k=5) # To persist: faiss.write_index(index, "index.faiss") # To load: index = faiss.read_index("index.faiss") # For GPU: index = faiss.index_cpu_to_all_gpus(index) # No metadata, no CRUD, no API -- you build all of that.

Redis Vector — In-Memory, Fast, Ephemeral

Redis Vector (RediSearch)

C RSALv2 / SSPL RESP + REST

Redis is an in-memory data structure store. With the RediSearch module (now called Redis Search), it gained vector similarity search capabilities alongside its existing full-text search, geospatial, and key-value features. Redis Vector is fast -- everything is in RAM -- and it can do hybrid search (full-text + vector) in a single query, like Elasticsearch. The HNSW index is used for ANN search.

The defining characteristic of Redis is that it is in-memory by default. This is a strength (speed) and a weakness (persistence). Redis can persist to disk via RDB snapshots or AOF (append-only file) logs, but by default, if Redis crashes, you lose everything since the last snapshot. For a vector database holding the index of your RAG corpus, this means you must configure persistence carefully, or accept that a crash requires re-indexing from the source documents. Redis is not the right choice for the primary, durable store of your RAG embeddings -- but it is an excellent choice for a caching layer, a real-time retrieval layer, or an ephemeral search index that can be rebuilt from a durable source.

License Note: Redis moved to RSALv2/SSPL licensing in 2024 (Redis 7.4+). This is not OSI-approved open source -- it is source-available with restrictions on providing Redis as a managed service. For sovereign on-premise use (running it yourself, on your own hardware, for your own use), this is fine. For embedding Redis in a product you sell to clients, review the license terms carefully. The older Redis 7.2 and prior are BSD-3-Clause. If the license matters for your use case, use Valkey -- the Linux Foundation fork of Redis that remains BSD-licensed and supports the same vector search module.

When to Choose Redis Vector

  • Caching layer for hot vectors in front of a durable database
  • Real-time retrieval where sub-millisecond latency is required
  • Ephemeral search indices that can be rebuilt from source
  • You already run Redis and want to add vector search without a new service
  • Hybrid search (full-text + vector) with in-memory speed
  • Session-based RAG where vectors are temporary (per-conversation context)
Strengths
  • Fastest search in this comparison (in-memory, C core)
  • Hybrid search (full-text + vector in one query)
  • Battle-tested infrastructure (Redis is ubiquitous)
  • Can serve as both vector DB and general-purpose cache/queue
  • HNSW index for ANN search
  • Optional persistence (RDB snapshots, AOF logging)
  • Valkey fork available if BSD license is required
Limitations
  • In-memory = high RAM cost (all vectors in RAM)
  • Ephemeral by default (persistence must be configured)
  • RSALv2/SSPL license (not OSI open source -- use Valkey for BSD)
  • Vector search is a module, not core Redis (must enable RediSearch)
  • RAM cost limits scale (billion-scale is extremely expensive in RAM)
  • No on-disk vector storage (everything in memory)
  • Not ideal as a primary durable vector store
# Redis with vector search (RediSearch module included) docker run -d --name redis-vector \ -p 6379:6379 \ -v /opt/redis/data:/data \ -e REDIS_ARGS="--appendonly yes --save 60 1000" \ --restart unless-stopped \ redis/redis-stack:latest # --appendonly yes enables AOF persistence (durable writes) # --save 60 1000 enables RDB snapshots every 60s if 1000+ keys changed # No GPU required. All in RAM -- size your RAM to your vector count. # For BSD license, use Valkey instead: # docker run -d --name valkey -p 6379:6379 valkey/valkey:latest

Elasticsearch / OpenSearch — Hybrid Search in One Query

Elasticsearch / OpenSearch

Java (JVM) Elastic License / Apache 2.0 REST + JSON

Elasticsearch (and its Apache 2.0 fork, OpenSearch) is a full-text search engine that added vector search (kNN) support. This makes it the only database in this comparison that does dense vector search and sparse (BM25) full-text search natively, in the same engine, in the same query. For hybrid search RAG -- where you combine semantic vector retrieval with keyword BM25 retrieval and fuse the results -- Elasticsearch/OpenSearch is the most integrated solution. You issue one query, it does both retrievals, and returns fused results.

The cost of this integration is weight. Elasticsearch is a JVM application. A single Elasticsearch node idles at 1-2GB RAM just for the JVM heap, before you load any data. A production cluster is at least three nodes for high availability, each with its own JVM. For a team that already runs Elasticsearch (for log search, product search, or analytics), adding vector search is a natural extension. For a team starting from scratch, standing up an Elasticsearch cluster for vector search alone is heavyweight compared to Qdrant.

OpenSearch vs. Elasticsearch: OpenSearch is the Apache 2.0 fork of Elasticsearch (created when Elastic changed its license in 2021). For sovereign deployments where license matters, OpenSearch is the better choice -- Apache 2.0 is unambiguously open source, while the Elastic License has restrictions on providing Elasticsearch as a managed service. Both support kNN vector search. OpenSearch is governed by the Linux Foundation and is vendor-neutral. We recommend OpenSearch over Elasticsearch for sovereign RAG.

When to Choose OpenSearch/Elasticsearch

  • Hybrid search RAG (dense + sparse in one query) is the primary requirement
  • You already run Elasticsearch/OpenSearch for full-text search
  • Use cases requiring complex relevance tuning (scoring, boosting, function_score)
  • Applications needing both vector search and aggregations/analytics on the same data
  • Teams with JVM operations experience
Strengths
  • Best hybrid search (dense + sparse in one query)
  • Mature full-text search (decades of development)
  • OpenSearch is Apache 2.0 (truly open source)
  • HNSW index for kNN search
  • Complex relevance tuning (scoring, boosting, script_score)
  • Aggregations and analytics on the same data as vectors
  • Large ecosystem (Beats, Logstash, Kibana/OpenSearch Dashboards)
  • Scale to billions of documents (distributed by design)
Limitations
  • Heaviest resource footprint in this comparison (JVM)
  • 1-2GB RAM idle per node (JVM heap)
  • 3+ nodes recommended for production (high availability)
  • Slower pure vector search than Qdrant or FAISS
  • Complex to operate (JVM tuning, shard management, mapping)
  • Elasticsearch license is not OSI open source (use OpenSearch)
  • Overkill if you only need vector search (no full-text)
# OpenSearch (Apache 2.0 fork of Elasticsearch) with kNN docker run -d --name opensearch \ -p 9200:9200 -p 9600:9600 \ -e "discovery.type=single-node" \ -e "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g" \ -e "DISABLE_SECURITY_PLUGIN=true" \ -v /opt/opensearch/data:/usr/share/opensearch/data \ --restart unless-stopped \ opensearchproject/opensearch:latest # For production: 3+ nodes, cluster mode, security plugin enabled. # Create a kNN index: # PUT /rag_docs { "mappings": { "properties": { # "embedding": { "type": "knn_vector", "dimension": 1024, # "method": { "name": "hnsw", "space_type": "cosil" } } } } } # No GPU required. JVM heap should be 50% of available RAM.

Vespa — Enterprise-Scale, Complex Ranking

Vespa

Java (JVM) Apache 2.0 REST + JSON

Vespa is Yahoo's open-source search and ranking engine, designed for enterprise-scale real-time applications. It is the most powerful and the most complex database in this comparison. Vespa is not just a vector database -- it is a full search and ranking platform that supports vector search, full-text search, tensor computation (for ML model scoring at query time), and custom ranking pipelines written in Java or Rust. If your RAG system needs to rank retrieved documents by a custom ML model at query time (not just by vector distance), Vespa is the only option here that does that natively.

For example, a medical RAG system might retrieve 100 candidate chunks by vector similarity, then re-rank them by a custom model that considers document recency, clinician trust score, patient-specific relevance, and source authority -- all computed at query time inside the database. This is Vespa's sweet spot. No other database in this comparison supports custom ranking functions executed at query time against the retrieved results.

The cost is extreme complexity. Vespa has a steep learning curve, a complex deployment model (multiple services: config server, container, search node, log server), and requires understanding of its application package model (schemas, ranking expressions, services). A Vespa deployment is a multi-day engineering effort even for experienced teams. For most sovereign RAG deployments, this complexity is not justified -- Qdrant with a re-ranking cross-encoder in your application code achieves similar results with far less infrastructure. Choose Vespa when the query-time ranking pipeline is the core of your application and you have the engineering team to operate it.

When to Choose Vespa

  • Large-scale production with custom ranking pipelines at query time
  • Use cases requiring ML model scoring inside the database (tensor computation)
  • Complex relevance tuning beyond what Elasticsearch scoring offers
  • Organizations with search engineering teams and JVM operations experience
  • Applications where ranking quality is the primary differentiator
Strengths
  • Custom ranking pipelines at query time (unique)
  • Tensor computation inside the database (ML model scoring)
  • Enterprise-scale (designed for Yahoo-scale traffic)
  • Real-time updates with immediate searchability
  • Apache 2.0 license
  • Hybrid search (vector + full-text + custom scoring)
  • Java and Rust ranking expression support
  • Distributed by design (true horizontal scaling)
Limitations
  • Most complex database in this comparison (steep learning curve)
  • Multi-service deployment (config server, container, search nodes)
  • JVM-based (heavy resource footprint)
  • Requires search engineering expertise to operate
  • Overkill for any deployment under 10M vectors
  • Smaller community than Elasticsearch or Milvus
  • Documentation is dense and assumes deep search knowledge
# Vespa -- standalone (development) docker run -d --name vespa \ -p 8080:8080 \ -v /opt/vespa/data:/opt/vespa/data \ --restart unless-stopped \ vespaengine/vespa:latest # Production requires: config server, container service, # search nodes, and a deployed application package (schema + ranking). # See Vespa documentation for application package deployment. # No GPU required for CPU-based ranking. JVM heap tuning critical.

Vald — Kubernetes-Native, NGT Algorithm

Vald

Go Apache 2.0 gRPC

Vald is a cloud-native vector database developed by Yahoo Japan. It is designed from the ground up for Kubernetes: it runs as a set of Kubernetes microservices, uses Kubernetes for service discovery, scaling, and fault tolerance, and is deployed via Helm chart. Its ANN algorithm is NGT (Neighborhood Graph and Tree), developed by the AIST (National Institute of Advanced Industrial Science and Technology, Japan). NGT is known for high recall and fast search, particularly for high-dimensional vectors.

Vald is the right choice if and only if your infrastructure is Kubernetes-native. If you are deploying RAG as part of a Kubernetes-based platform and want a vector database that fits naturally into that ecosystem -- Helm deployment, Kubernetes-native scaling, microservice architecture, gRPC API -- Vald is purpose-built for it. If you are not on Kubernetes, Vald is the wrong choice. It does not have a simple single-container deployment like Qdrant; it expects a Kubernetes cluster.

The NGT algorithm is Vald's technical differentiator. NGT builds a graph-based index that achieves high recall at high speeds, especially for high-dimensional vectors (768d, 1024d, 1536d). For RAG systems using modern embedding models (which produce high-dimensional vectors), this is a meaningful advantage over IVF-based indexes. However, HNSW (used by Qdrant, pgvector, and others) is also a graph-based index with similar characteristics, so the practical advantage of NGT over HNSW is modest in most workloads.

When to Choose Vald

  • Kubernetes-native deployments (this is a hard requirement)
  • Organizations with Kubernetes operations expertise
  • Use cases wanting NGT's high-recall high-dimensional search
  • Microservice architectures where gRPC and Helm fit naturally
  • Teams that want a vector database that scales with Kubernetes
Strengths
  • Kubernetes-native (Helm, microservices, k8s scaling)
  • NGT algorithm (high recall for high-dimensional vectors)
  • Apache 2.0 license
  • gRPC API (high-throughput, typed)
  • Distributed by design (microservice architecture)
  • Auto-scaling with Kubernetes HPA
  • Designed for cloud-native deployments
Limitations
  • Requires Kubernetes (no standalone deployment)
  • Steep learning curve if you are not already on Kubernetes
  • Smaller community than Qdrant, Milvus, or Weaviate
  • Less documentation and fewer tutorials than competitors
  • No payload filtering as sophisticated as Qdrant
  • No built-in full-text search (vector-only)
  • Niche adoption (primarily Yahoo Japan ecosystem)
# Vald -- requires Kubernetes. No simple docker run. # Deploy via Helm: helm repo add vald https://vald.vdaas.org/charts helm install vald vald/vald \ --namespace vald \ --create-namespace \ -f values.yaml # Prerequisites: Kubernetes cluster, Helm 3, kubectl. # Vald runs as multiple microservices (agent, gateway, manager, etc.) # No GPU required for NGT CPU search. GPU support is limited.

Why Not Pinecone (and Other Cloud-Only Databases)

Pinecone — Cloud-Only (Not for Sovereign RAG)

Cloud-Only Not Self-Hostable

Pinecone is a managed vector database. It is a good product -- fast, well-documented, with features like serverless scaling, hybrid search, and integrated embedding. But it is cloud-only. There is no self-hosted Pinecone. Your vectors live on Pinecone's servers, accessed through Pinecone's API, governed by Pinecone's terms of service. You cannot run Pinecone on your own hardware. This makes Pinecone fundamentally incompatible with sovereign RAG.

We mention Pinecone here only to explain why it is excluded from the rest of this comparison, and to address the common question: "Why not just use Pinecone?" The answer has three parts.

1. Your embeddings leave your network. When you store embeddings in Pinecone, you transmit your document embeddings to Pinecone's servers over the internet. Embeddings are not raw text, but they are reversible. Given access to the embedding model and the embedding vectors, an attacker can perform inversion attacks to recover approximate source text. For HIPAA-regulated medical records, attorney-client-privileged documents, and proprietary source code, transmitting embeddings to a third party is an unacceptable data exposure -- regardless of the provider's compliance certifications.
2. You depend on someone else's uptime and access policies. If Pinecone has an outage, your RAG system is down. If Pinecone changes its API, you must update your code. If Pinecone changes its pricing, your costs change. If Pinecone decides your usage violates its terms of service, your database is shut off. A sovereign RAG system must be operable without any dependency on a third party's availability, policies, or business decisions. On-premise Qdrant, pgvector, or Milvus have no such dependency.
3. You cannot audit the data path. In a sovereign deployment, you control the network, the access logs, the audit trail, and the data-at-rest encryption. With Pinecone, the data path goes through Pinecone's network, Pinecone's access logs, and Pinecone's audit trail. You cannot verify that your embeddings were not logged, indexed, or used for model training. You must trust Pinecone's claims. Sovereignty is about not having to trust -- it is about being able to verify.

The same reasoning applies to other cloud-only vector databases and cloud-hosted versions of self-hostable databases (e.g., Zilliz Cloud for Milvus, Weaviate Cloud Services, Elastic Cloud). These services are fine for non-sensitive data and for teams that have accepted cloud dependency. For sovereign RAG -- medical, legal, proprietary, personal -- they are excluded by design.

The Rule: If the vector database runs on someone else's servers, it is not sovereign. Every database in the comparison table below can be deployed on hardware you control, from a Docker image or source you can audit, with no network dependency on a third party. That is the minimum requirement for sovereign RAG.

Master Comparison Table

The table below covers every self-hostable vector database relevant to RAG, plus Pinecone (marked as cloud-only) for reference. Sovereign-friendly rating reflects: license permissiveness, self-hostability, audit-ability, and zero cloud dependency. A database rated "Excellent" is Apache 2.0 or MIT, fully self-hostable, and has no cloud dependency in its default deployment.

Database Language License Max Scale API Multi-Modal Persistence Distributed Payload Filter Hybrid Search Quantization Best For Sovereign Rating
pgvector C (Postgres ext.) PostgreSQL ~10M vectors SQL Any dim Disk (Postgres WAL) ~ Via Citus/manual SQL WHERE Via pg_bm25/pg_trgm No (full precision) Teams already on Postgres; ACID + vectors. Excellent
Chroma Python (DuckDB) Apache 2.0 ~500K vectors Python SDK + REST Any dim Disk (DuckDB file) No ~ Basic where No No Prototyping, small datasets, dev environments. Excellent
Weaviate Go BSD-3-Clause ~100M vectors GraphQL + REST Text + image built-in Disk + RAM Sharding + replication GraphQL filters Built-in BM25 + vector ~ Some (PQ) Multi-modal RAG, GraphQL-preferring teams. Good
Milvus C++ / Go Apache 2.0 ~10B vectors gRPC + REST Any dim Disk (object storage) Sharding + replication Metadata filtering ~ Via scalar field IVF-PQ, SQ8, GPU Enterprise 100M+ vectors, GPU-accelerated search. Excellent
LanceDB Rust Apache 2.0 ~100M vectors Python + Rust SDK Columnar (any data) Disk (Lance format) Single-node SQL-like filter No IVF-PQ Edge, embedded, single-user, no-server RAG. Excellent
FAISS C++ / Python MIT ~1B vectors (in RAM) Library (no API) Any dim ~ File (manual) Build it yourself Post-search only No IVF-PQ, SQ, GPU Custom systems, max control, max speed. Excellent
Redis Vector C RSALv2 / SSPL ~100M (RAM-limited) RESP + REST Any dim RAM (RDB/AOF optional) ~ Redis Cluster Tag/numeric filters Full-text + vector No Caching, real-time, ephemeral retrieval. Fair (license)
OpenSearch Java (JVM) Apache 2.0 ~1B documents REST + JSON Any dim Disk (Lucene segments) Sharding + replication Query DSL (rich) BM25 + kNN in one query ~ Limited Hybrid search RAG, existing ES/OS users. Good
Elasticsearch Java (JVM) Elastic License ~1B documents REST + JSON Any dim Disk (Lucene segments) Sharding + replication Query DSL (rich) BM25 + kNN in one query ~ Limited Same as OpenSearch but non-OSI license. Fair (license)
Vespa Java (JVM) Apache 2.0 ~10B documents REST + JSON Tensors (any) Disk + RAM Sharding + replication Ranking expressions Full-text + vector + custom ~ Some Enterprise with custom query-time ranking. Good
Vald Go Apache 2.0 ~1B vectors gRPC Any dim Disk + RAM Kubernetes-native ~ Basic No ~ NGT optimization Kubernetes-native deployments. Good
Pinecone Proprietary Proprietary (SaaS) Cloud-defined REST Any dim Cloud (no control) Cloud-managed Metadata filter Hybrid search Serverless Not for sovereign RAG. Cloud dependency. Not Sovereign
Reading the table: "Excellent" sovereign rating = Apache 2.0 or MIT, fully self-hostable, no cloud dependency, auditable from source. "Good" = BSD or Apache 2.0 but heavier to operate (JVM, Kubernetes). "Fair" = license concerns (SSPL, Elastic License) or significant operational caveats. "Not Sovereign" = cloud-only, cannot be self-hosted.

Feature Matrix: At a Glance

A focused feature checklist for quick comparison. = supported natively. ~ = partially supported or requires configuration/add-ons. = not supported.

Feature Qdrant pgvector Chroma Weaviate Milvus LanceDB FAISS Redis OpenSearch Vespa Vald
HNSW Index ~ (NGT)
IVF Index IVFFlat IVF-PQ IVF-PQ ~ IVF
GPU Acceleration CAGRA ~
Quantization int8 + PQ ~ PQ + SQ PQ PQ + SQ ~ ~ ~
Payload/Metadata Filter Pre-filter SQL WHERE ~ Basic GraphQL Post-search Query DSL ~
Full-Text / BM25 Search ~ Via pg_bm25
Hybrid Search (one query) ~ Manual ~ 2.4+
Multi-Modal (text+image) Built-in Columnar
Distributed / Cluster ~ Citus ~
ACID Transactions ~ ~
On-Disk Storage (RAM-light) ~
Single-Container Deploy ~ Standalone No container No container
No External Dependencies etcd+MinIO+Pulsar Multi-service Kubernetes

Decision Guide: Which Vector Database to Choose

The decision below is keyed to use case, not to feature checklist. Start with your scenario, read the recommendation, and if there is a runner-up that fits a secondary constraint, note it. Every recommendation here assumes sovereignty (on-premise, self-hosted) is a hard requirement -- if it is not, the calculus changes, but this page is about sovereign RAG.

Small Business / General RAG
Most sovereign RAG deployments
→ Qdrant
Runner-up: pgvector (if you already run Postgres)

You have 10K to 10M vectors, no existing database infrastructure, and want the fastest path to a working sovereign RAG system. Qdrant's single-container Docker deployment, Apache 2.0 license, and excellent payload filtering make it the default. Deploy in minutes, scale to millions of vectors on a single VM.

Existing PostgreSQL Shop
You already run Postgres in production
→ pgvector
Runner-up: Qdrant (if you exceed 10M vectors)

Your application already uses PostgreSQL for relational data. Adding pgvector means one database instead of two, ACID transactions that include vector operations, and reuse of your existing backups, replication, and monitoring. Stay under 10M vectors and you get good performance with zero new infrastructure.

Enterprise / 100M+ Vectors
Billion-scale distributed search
→ Milvus
Runner-up: Qdrant distributed (up to ~100M)

You have 100M to 10B vectors, a Kubernetes cluster, and a DevOps team. Milvus's distributed mode, GPU-accelerated indexes, and billion-scale design are purpose-built for this. The operational complexity is justified by the scale. If you are under 100M, Qdrant's distributed mode is simpler and sufficient.

Medical / Regulated Data
HIPAA, attorney-client, proprietary
→ Qdrant
Runner-up: pgvector (if ACID required)

Sensitive data that must never leave your network. Qdrant on a single in-house server, with audit logging and network isolation, gives you a vector database that is fast, lightweight, and completely under your control. If your records system requires atomic writes of patient records + embeddings, pgvector gives you ACID transactions that Qdrant cannot.

Edge / Embedded / No Server
Laptop, Raspberry Pi, kiosk, offline
→ LanceDB
Runner-up: Chroma (for small prototypes)

You cannot or do not want to run a database server -- edge devices, embedded applications, single-user desktop tools. LanceDB is embedded (no server, no Docker, no port), stores vectors in a Lance file on disk, and searches them through a Python or Rust SDK. SQLite for vectors. Zero infrastructure.

Multi-Modal RAG
Text + images + audio in one DB
→ Qdrant (with payload modality field)
Runner-up: Weaviate (built-in multi2vec)

You need to store and retrieve across text, image, and audio embeddings in the same collection. Qdrant does this with a modality field in the payload and gives you full control. Weaviate does this with built-in multi2vec modules and cross-modal search, but requires configuring local embedding modules for sovereignty. Choose Weaviate if you want the built-in workflow; Qdrant if you want maximum control and speed.

Hybrid Search (Dense + Sparse)
BM25 + vector in one query
→ OpenSearch
Runner-up: Weaviate, Redis, Elasticsearch

Your RAG system needs to combine keyword (BM25) and semantic (vector) retrieval in a single fused query. OpenSearch (Apache 2.0 fork of Elasticsearch) does this natively with the most mature full-text engine in this comparison. Choose Weaviate or Redis for lighter-weight hybrid search. Choose Qdrant + a separate BM25 index (Postgres FTS or Elasticsearch) if you want best-of-breed for each.

Real-Time / Caching Layer
Sub-millisecond, ephemeral retrieval
→ Redis Vector (or Valkey)
Runner-up: Qdrant (for durable primary store)

You need sub-millisecond vector search for real-time applications, or you want a caching layer in front of a durable database. Redis (or Valkey, the BSD fork) is in-memory and fast. Use it for hot vectors and session-based RAG context. Pair it with Qdrant as the durable primary store, and re-populate Redis from Qdrant on restart.

Custom System / Max Control
You want to build your own database
→ FAISS
Runner-up: Qdrant (if you reconsider)

You have a specific need that no existing database meets -- unusual index types, extreme performance, integration with a custom storage layer. FAISS gives you the search engine; you build the database around it. This is the most engineering work but the most control. Most teams should reconsider and use Qdrant, but if you have the engineering capacity and the specific need, FAISS is the foundation.

Kubernetes-Native Deployment
Your infrastructure is k8s
→ Vald
Runner-up: Milvus (Helm chart), Qdrant (Helm chart)

You run everything on Kubernetes and want a vector database that deploys and scales natively in that ecosystem. Vald is purpose-built for Kubernetes with Helm charts, microservice architecture, and k8s-native scaling. If you want a simpler option that also has Helm charts, Qdrant and Milvus both support Kubernetes deployment.

Custom Ranking Pipeline
ML model scoring at query time
→ Vespa
Runner-up: Qdrant + re-ranker in app code

Your RAG system retrieves candidates and then re-ranks them by a custom ML model that considers recency, authority, user context, and other factors -- all computed at query time inside the database. Vespa is the only option here that does this natively. For most use cases, Qdrant retrieval followed by a cross-encoder re-ranker in your application code achieves similar results with less infrastructure.

Prototyping / Development
Proof of concept, evaluation
→ Chroma
Runner-up: LanceDB, Qdrant (single container)

You are building a proof of concept, testing chunking strategies, or evaluating embedding models. Chroma's pip install and in-process mode get you from zero to storing and searching vectors in under five minutes. When you move to production, migrate to Qdrant (the API differences are small if you use the server mode).

🎯 The Default Recommendation: If you are unsure, choose Qdrant. It is the best general-purpose vector database for sovereign RAG: fast, lightweight, Apache 2.0, single-container deployment, excellent payload filtering, and scales from 10K to ~1B vectors. You can always migrate later -- the vector embeddings are portable (they are just arrays of floats), and moving from Qdrant to pgvector or Milvus is a data migration, not a re-embedding. Start with Qdrant, and if a specific need pulls you elsewhere, you will know which one and why.

Docker Deployment Notes

Deployment notes for each database, focused on the fastest path to a sovereign, on-premise installation. Every database below can be deployed from a Docker image you pull and run on your own hardware, with no network dependency on a third-party API. Volume mounts persist data to host storage so containers can be recreated without data loss.

Qdrant
Single container · No dependencies · CPU-only
  • docker run qdrant/qdrant
  • Ports: 6333 (REST), 6334 (gRPC)
  • Volumes: /qdrant/storage, /qdrant/snapshots
  • RAM: ~100MB idle, scales with collection size
  • GPU: Not required, not used
  • Backup: Snapshot API or file copy of storage volume
pgvector
Single container · No dependencies · CPU-only
  • docker run pgvector/pgvector:pg16
  • Port: 5432 (PostgreSQL)
  • Volume: /var/lib/postgresql/data
  • RAM: ~256MB idle (Postgres shared buffers)
  • GPU: Not required, not used
  • Backup: pg_dump or pg_basebackup
  • Requires: CREATE EXTENSION vector after first start
Chroma
Single container or in-process · CPU-only
  • docker run chromadb/chroma or pip install chromadb
  • Port: 8000 (server mode)
  • Volume: /chroma/chroma
  • RAM: ~200MB idle (Python + DuckDB)
  • GPU: Not required, not used
  • Backup: File copy of data directory
Weaviate
Single container (standalone) · CPU-only
  • docker run semitechnologies/weaviate
  • Port: 8080 (REST/GraphQL)
  • Volume: /var/lib/weaviate
  • RAM: ~500MB idle (Go runtime)
  • GPU: Not required (embedding modules may need GPU)
  • Backup: Built-in backup API or file copy
  • Note: Configure modules for local embedding (not cloud APIs)
Milvus
Multi-container (production) · GPU optional
  • Standalone: docker run milvusdb/milvus standalone
  • Production: docker-compose with etcd + MinIO + Pulsar
  • Ports: 19530 (gRPC), 9091 (metrics)
  • RAM: 2GB+ idle (all services)
  • GPU: Optional for GPU_IVF, GPU_CAGRA indexes
  • Backup: MinIO bucket snapshot
  • Note: Use Helm chart for Kubernetes deployment
LanceDB
No container needed · CPU-only
  • pip install lancedb -- no Docker
  • No port (embedded, in-process)
  • Storage: Directory on filesystem (Lance format)
  • RAM: Minimal (disk-based index)
  • GPU: Not required, not used
  • Backup: File copy of data directory
FAISS
No container needed (library) · GPU optional
  • pip install faiss-cpu or faiss-gpu
  • No port (library, in-process)
  • Storage: Manual (faiss.write_index to file)
  • RAM: All vectors in memory
  • GPU: Optional (faiss-gpu for GPU indexes)
  • Backup: Save index file, persist manually
  • Note: You build the persistence + API layer yourself
Redis Vector
Single container · CPU-only · In-memory
  • docker run redis/redis-stack (or Valkey for BSD)
  • Port: 6379 (RESP)
  • Volume: /data (RDB + AOF)
  • RAM: All vectors in memory (size accordingly)
  • GPU: Not required, not used
  • Backup: RDB snapshot or AOF file
  • Note: Enable --appendonly yes for durability
OpenSearch
Single container (dev) or cluster · CPU-only
  • docker run opensearchproject/opensearch
  • Ports: 9200 (REST), 9600 (metrics)
  • Volume: /usr/share/opensearch/data
  • RAM: 2GB+ idle (JVM heap, set -Xms2g -Xmx2g)
  • GPU: Not required, not used
  • Backup: Snapshot API to shared storage
  • Production: 3+ nodes, cluster mode, security plugin
Vespa
Multi-service · CPU-only · Complex
  • docker run vespaengine/vespa (standalone dev)
  • Port: 8080 (REST)
  • Volume: /opt/vespa/data
  • RAM: 2-4GB+ idle (JVM)
  • GPU: Not required, not used
  • Backup: Vespa content node snapshot
  • Production: config server + container + search nodes
Vald
Kubernetes required · CPU-only
  • helm install vald vald/vald
  • Ports: Via Kubernetes services (gRPC)
  • Volumes: Via Kubernetes PVCs
  • RAM: Scales with pod count
  • GPU: Limited support
  • Backup: Volume snapshot of agent pods
  • Requires: Kubernetes cluster + Helm 3

Resource Requirements

Resource requirements for a representative sovereign RAG deployment: 1 million vectors at 1024 dimensions (the output dimension of many modern embedding models like BGE-large and E5-large). "Idle" is the RAM consumed by the database process with an empty or small collection. "Working" is the RAM consumed with 1M 1024d vectors loaded and actively serving queries. GPU requirements are for the database itself -- embedding model inference (running the embedding model to generate vectors) is a separate concern and may require GPU regardless of database choice.

Database Idle RAM Working RAM (1M × 1024d) CPU Disk GPU Needed? Deployment Weight
Qdrant ~100 MB ~1.5 GB (with int8 quantization: ~500 MB) 1-2 cores ~4 GB (vectors on disk) No Light (1 container)
pgvector ~256 MB ~2.5 GB (no quantization) 2-4 cores ~4 GB No Light (1 container)
Chroma ~200 MB ~2 GB (DuckDB, no quantization) 1-2 cores ~4 GB No Very light (pip or 1 container)
Weaviate ~500 MB ~3 GB 2-4 cores ~4 GB No (modules may) Medium (1+ containers with modules)
Milvus (standalone) ~2 GB ~4 GB (with PQ: ~1 GB) 4+ cores ~8 GB Optional (GPU indexes) Heavy (4+ services in production)
LanceDB ~50 MB ~800 MB (disk-based IVF-PQ) 1 core ~4 GB (Lance columnar) No Minimal (no server)
FAISS ~50 MB ~4 GB (all in RAM, no quant.) / ~1 GB (PQ) 1-4 cores ~4 GB (index file) Optional (faiss-gpu) Minimal (library, you build infra)
Redis Vector ~100 MB ~4 GB (all in RAM, no quant.) 2-4 cores ~4 GB (RDB/AOF) No Light (1 container)
OpenSearch ~2 GB (JVM) ~4 GB (JVM + vectors) 4+ cores ~6 GB (Lucene segments) No Heavy (1+ nodes, JVM tuning)
Vespa ~2-4 GB (JVM) ~6 GB 4+ cores ~6 GB No Very heavy (multi-service)
Vald ~1 GB (k8s pods) ~3 GB 2-4 cores ~4 GB No (limited) Heavy (Kubernetes + pods)
GPU Note: GPU is not required for any vector database in this comparison for CPU-based search (HNSW, IVF). GPU is beneficial for: (1) Milvus GPU indexes (GPU_IVF, GPU_CAGRA) at very large scale, (2) FAISS GPU indexes for maximum pure search speed, and (3) the embedding model inference itself -- which is separate from the database. For a typical sovereign RAG deployment (under 10M vectors), CPU-only search is fast enough (sub-10ms p99 with Qdrant). Spend your GPU budget on the LLM and embedding model, not the vector database.
🎯 The Practical Resource Rule: For a sovereign RAG deployment with Qdrant on a single server: 8GB RAM, 4 CPU cores, and 50GB disk will comfortably handle 1 million 1024-dimensional vectors with int8 quantization, serving 100+ queries per second at sub-10ms latency. No GPU required for the database. The same server can run the LLM if it has a GPU (for inference) -- the vector database and the LLM coexist on one machine for deployments up to ~5M vectors.

Key Takeaways

1. Default to Qdrant. For the majority of sovereign RAG deployments, Qdrant is the right choice: fast (Rust), lightweight (~100MB idle), Apache 2.0, single-container Docker deployment, best-in-class payload filtering, and scales from thousands to ~1 billion vectors. Start here unless a specific need pulls you elsewhere.
2. Use pgvector if you already run Postgres. One database instead of two, ACID transactions with vectors, reuse of existing Postgres infrastructure. Stay under 10M vectors and you get good performance with zero new operational burden.
3. Use Milvus only for 100M+ vectors. Milvus is the right tool for billion-scale, GPU-accelerated, distributed deployments with Kubernetes. It is overkill for anything under 100M vectors, where Qdrant is simpler and sufficient.
4. Use LanceDB for edge and embedded. When you cannot run a server -- edge devices, embedded applications, single-user desktop tools -- LanceDB is the SQLite of vector databases. No server, no Docker, no port. Just a library and a file on disk.
5. Avoid cloud-only databases for sovereign RAG. Pinecone and other cloud-only vector databases send your embeddings to a third party's servers. For medical, legal, proprietary, or personal data, this is an unacceptable exposure. Every database in this comparison can be self-hosted -- choose one of those.
6. Embeddings are portable; databases are not permanent. Your vector embeddings are arrays of floats. They are not tied to any database. If you start with Qdrant and later need Milvus for scale, you export the vectors and load them into Milvus. You do not re-embed your documents (the expensive step). This means the database choice is reversible -- choose the simplest option that works now, and migrate when you have a concrete reason to.

Build Your Sovereign RAG System

Avondale.AI designs and deploys sovereign, on-premise RAG systems with the vector database that fits your use case -- Qdrant by default, pgvector for Postgres shops, Milvus for enterprise scale, LanceDB for edge. Your embeddings never leave your network. Your vector database runs on hardware you control. Contact us to start building a RAG system that retrieves from your data without showing it to anyone else.

Get Started Back to Technical Library