
Vector DB Comparison: pgvector, Qdrant, Milvus, LanceDB
A technical comparison of pgvector, Qdrant, Milvus, and LanceDB for backend developers and architects building RAG systems.
Vector Databases Compared: pgvector, Qdrant, Milvus, and LanceDB
In Retrieval-Augmented Generation (RAG) architectures, the vector database is not merely a storage bucket; it is the engine that resolves the semantic gap between user queries and unstructured data. Selecting the right backend requires understanding how each system manages memory, indexing, and distribution. This analysis compares pgvector, Qdrant, Milvus, and LanceDB by examining their underlying mechanisms, operational footprints, and specific trade-offs for backend engineers. This article is Part 4 of the RAG from Zero to Production series.
The Landscape: pgvector as a Relational Extension
pgvector is an open-source extension for PostgreSQL that enables vector similarity search. It does not run as a separate service but operates within the existing PostgreSQL process space, leveraging the database's existing infrastructure.
Mechanism: pgvector supports three index types: IVFFlat, HNSW, and distance metrics like L2, Cosine, and Inner Product. For detailed implementation specifics, refer to the official pgvector documentation.
- IVFFlat: Divides vectors into lists (clusters) and searches the nearest lists. It is faster to build but less accurate than HNSW for large datasets.
- HNSW (Hierarchical Navigable Small World): Constructs a multi-layered graph where nodes connect to their nearest neighbors. This allows for logarithmic time complexity in search operations but requires more memory to maintain the graph structure.
Operational Profile:
Since pgvector runs inside PostgreSQL, it inherits ACID transactions, concurrency control, and SQL query capabilities. This allows you to join vector similarity results with relational metadata (e.g., filtering category='finance' before or after vector search) natively.
Trade-off: The primary constraint is horizontal scaling. While PostgreSQL can be scaled vertically (larger CPU/RAM), adding read replicas does not automatically distribute the vector index search load efficiently across nodes for write-heavy workloads. If your vector dataset exceeds available RAM, HNSW performance degrades significantly due to disk I/O. Use pgvector when you want to avoid introducing a new infrastructure component and your dataset fits comfortably within a single node’s memory.
Standalone Distributed Engines: Qdrant and Milvus
For dedicated vector search, standalone engines offer specialized optimizations that general-purpose databases cannot match. We contrast Qdrant’s efficiency with Milvus’s distributed scale.
Qdrant: High-Performance Standalone
Qdrant is a vector database written in Rust, designed for high-throughput similarity search. Unlike pgvector, it is a standalone service with its own API and storage engine.
Mechanism: Qdrant primarily uses HNSW graphs optimized for speed. Its key innovation is "quantization" and payload filtering. Qdrant stores vectors and associated metadata (payloads) separately in memory and on disk, allowing for efficient filtering before vector search. It also supports sparse vectors for keyword matching, enabling hybrid search without external tools. See the Qdrant documentation for technical details.
Operational Profile: Qdrant offers a single-binary deployment model that is easy to containerize. It provides a REST and gRPC API. For horizontal scaling, Qdrant uses a distributed mode where data is sharded across multiple nodes, and search requests are broadcast to all shards and aggregated.
Trade-off: Qdrant is easier to deploy and manage than Milvus but lacks the extreme scale-out capabilities of fully distributed systems like Milvus. It is ideal for mid-scale RAG applications where low latency is critical, and the dataset fits within a cluster’s total memory. The Rust implementation ensures low latency and high CPU efficiency.
Milvus: The Distributed Scale Engine
Milvus is a cloud-native vector database built for massive scale. It is architected as a set of microservices, separating storage and compute.
Mechanism: Milvus’s architecture consists of four main components:
- Proxy: Routes requests.
- QueryNode: Handles search and query execution (holds the HNSW index in memory).
- DataNode: Manages data ingestion.
- CoordNode: Oversees cluster state.
Storage is decoupled from compute. Vectors can be stored in object storage (S3, MinIO) or local disk, while the QueryNodes cache hot data in memory. This allows you to scale search capacity (QueryNodes) independently of storage capacity. For more on the architecture, see the Milvus documentation.
Operational Profile: Milvus is complex. Running it in production typically requires Kubernetes, etcd for coordination, and MinIO/S3 for storage. It supports automatic sharding and load balancing across thousands of nodes.
Trade-off: Milvus is the most complex to operate but offers the highest scalability. It is suitable for enterprise-grade RAG systems processing billions of vectors with strict SLAs. The separation of storage and compute means you pay for compute only when searching, but the operational overhead is significant. Use Milvus if you anticipate scaling beyond tens of millions of vectors or require high availability with automatic failover.
Embedded Search with LanceDB
LanceDB takes a different approach by co-locating the vector index and data with the application code, eliminating the need for a separate networked database service.
Mechanism: LanceDB uses the Lance file format, an open-source columnar data format optimized for machine learning workloads. It stores vectors in Parquet-like files on disk or in object storage (S3). The index (IVF-PQ or HNSW) is built directly on these files. When a query is issued, LanceDB uses memory mapping (mmap) to read only the necessary pages from disk, avoiding full data loading into RAM. Refer to the LanceDB documentation for implementation details.
Operational Profile: LanceDB can be used as an in-process library (e.g., in Python, Node.js, or Rust) or as a standalone server. In embedded mode, there is no network overhead for data transfer between the application and the database. It supports metadata filtering via SQL-like filter expressions, which is often used in conjunction with vector search, though this differs from the dense+sparse fusion definition of hybrid search established earlier. See LanceDB operational docs for more on usage patterns.
Trade-off: LanceDB excels in scenarios where data locality is key, such as edge devices, local development, or applications where minimizing latency by removing network hops is critical. However, it does not offer distributed clustering out of the box. If you need to scale across multiple servers, you must implement sharding logic in your application layer. Use LanceDB for local-first applications, prototypes, or when integrating vector search directly into existing Python/Rust services without managing a separate database cluster.
Decision Matrix for RAG
Synthesizing these mechanisms into architectural choices based on latency, scale, and infrastructure footprint:
| Feature | pgvector | Qdrant | Milvus | LanceDB |
|---|---|---|---|---|
| Deployment | PostgreSQL Extension | Standalone Service | Microservices (K8s) | Embedded / Standalone |
| Scale | Single Node | Cluster (Sharded) | Massive Cluster (Decoupled) | Single Node / App-Level |
| Latency | Moderate (DB Overhead) | Low (Rust Optimized) | Low (Memory Mapped) | Very Low (Zero Network) |
| Complexity | Low | Medium | High | Low |
| Best For | Small/Medium RAG, SQL Integration | Mid-Scale RAG, Hybrid Search | Enterprise Scale, Billions of Vectors | Local/Edge Apps, Prototypes |
Conclusion
The choice depends on your infrastructure maturity and scale. If you already use PostgreSQL and have fewer than 10 million vectors, pgvector minimizes operational friction. For dedicated vector search with moderate scale, Qdrant offers a balanced performance-to-complexity ratio. Milvus is the correct choice for massive, distributed datasets where compute and storage must scale independently. LanceDB is ideal for embedded scenarios where data locality and minimal latency are paramount. Evaluate your data volume, latency requirements, and team’s ability to manage infrastructure complexity before selecting a backend.
Related posts
Choosing an Embedding Model in 2026
A practical guide for ML engineers on selecting the right embedding model for RAG systems in 2026, covering MTEB benchmarks, Matryoshka representations, and multilingual support.
Estimating LLM Costs Before You Build
A practical guide for engineering managers and architects on estimating LLM costs using unit economics, token forecasting, and sensitivity analysis to build within budget.
Multi-Provider Failover with LiteLLM
Implement resilient AI routing using LiteLLM to handle multi-provider failover and fallback strategies for backend systems.