Summary
For one million code vectors, Qdrant, Milvus and pgvector can all serve approximate nearest-neighbor searches, but their latency depends on index settings, filtering, hardware and the recall you require. We did not run a controlled head-to-head test for this article, so it reports no fabricated latency figures; instead, it provides a concrete test protocol, sizing calculations and decision guidance for producing valid results on your own workload.
1. Quick Verdict
Choose Qdrant when vector search is a primary capability, you want a purpose-built service with a relatively direct single-node setup, and its payload-filtering and operational model fit your application. Choose Milvus when you anticipate a vector-search service that needs a broader distributed architecture or want to evaluate its range of index and deployment options. Choose pgvector when vectors belong alongside relational records, SQL joins and PostgreSQL transactions—and your team would rather operate one database than add a separate vector service.
There is no defensible universal latency ranking from the product names alone. A single-node Milvus deployment and a distributed Milvus deployment are different test subjects; the same is true of self-managed and cloud services. If a vendor or article claims a winner, check that the hardware, dataset, filters, recall and measurement method match your use case.
At a glance: for a code-search pilot already using PostgreSQL, start with pgvector and measure it before adding infrastructure. For a dedicated vector-search service, benchmark Qdrant and Milvus alongside it. Treat p95 latency at an agreed recall level—not the lowest isolated p50—as the useful decision metric.
2. Feature-by-Feature Comparison
| Area | Qdrant | Milvus | pgvector |
|---|---|---|---|
| Product model | Purpose-built vector search engine with self-hosted and managed options. | Purpose-built vector database with standalone and distributed deployment choices; Zilliz Cloud is its managed-service option. | Open-source PostgreSQL extension; vectors live in ordinary PostgreSQL tables and use PostgreSQL query and transaction features. |
| Approximate nearest-neighbor index | HNSW is available. Tune graph construction and search settings against recall and memory needs. | HNSW is available, alongside other index types. Match the index type and parameters to the use case. | HNSW and IVFFlat are available. HNSW is a reasonable starting point for a comparable graph-index test. |
| Relational queries and joins | Supports payload filtering, but it is not a general-purpose relational database. | Supports scalar fields and filtering; it is not a replacement for a full relational application database. | Best fit when PostgreSQL is already central Supports SQL, transactions and joins with the vector extension. |
| Filtering considerations | Index payload fields used in filters and test filter selectivity; filtered search behavior can affect latency and recall. | Choose scalar indexes and validate the interaction between filtering and vector search for the deployed version. | Use appropriate SQL indexes for filter columns and inspect query plans. A vector index does not guarantee that the whole filtered query is fast. |
| Scaling and operations | Offers a dedicated service model; evaluate replication, snapshots, resource settings and deployment topology for your needs. | Has standalone and distributed modes. Distributed operation can add components and network hops, so benchmark the topology you intend to run. | Fits existing PostgreSQL operations, but vector indexes consume database resources and can affect vacuuming, backups, upgrades and other queries. |
| Best initial evaluation | Dedicated vector search with operational simplicity as a priority. | Vector workloads expected to need a distributed deployment or a wider choice of vector indexing options. | Code search that benefits from SQL, existing PostgreSQL data and fewer services. |
| Primary caution | Do not assume payload filters have identical costs across engines or data distributions. | Do not compare a distributed topology with another product's single node and call the result an engine-only comparison. | Do not benchmark only vector-only queries if production also performs joins, writes and transactional reads. |
All three support approximate search, so compare them at equivalent recall rather than simply using each product's default settings. HNSW parameters are similarly named across products but are not guaranteed to produce identical graphs, memory use or search behavior. Record exact software releases, index definitions and query parameters in every result.
3. Real-World Workflow Tests
Important: the workflows below are a reproducible benchmark plan, not test results from this article. No latency measurements are reported because no controlled run on the stated testbed was conducted. Use this methodology to create results you can trust and compare them with your production workload.
Testbed and dataset specification
- Reference machine: one AWS EC2 m7i.4xlarge with 16 vCPUs and 64 GiB RAM, plus a provisioned 1 TiB gp3 EBS volume. Use the same machine class, storage configuration, region and availability-zone placement for each single-node candidate. Record the actual CPU, kernel, storage throughput and IOPS settings.
- Dataset: one million code chunks, each represented by a 768-dimensional float32 vector. The vectors alone occupy 3.072 GB in decimal units (about 2.86 GiB); this excludes index structures, metadata, database overhead and replicas. Store the same stable chunk ID, repository ID, language and path fields in every system.
- Embeddings: pin one model and immutable model revision for all candidates. For example, use jinaai/jina-embeddings-v2-base-code if its model card and license suit your project. Keep chunking, preprocessing, normalization and query-vector generation identical. Do not include embedding-generation time in database-search latency.
- Index: begin with cosine distance and HNSW in all three systems. Use a matched starting configuration, such as M=16 and construction ef=200 where the product exposes comparable controls; record each product's exact setting and limitations. Do not assume equal parameter values mean equal index quality.
- Load method: bulk-load the same vectors and metadata, wait for indexing to finish, and verify counts. Run a warm-up, then measure at least 10,000 queries per workload with a fixed concurrency schedule. Repeat each run at least three times and report the distribution and run-to-run variation.
- Accuracy: build exact top-k ground truth on a manageable sample or with a separate exact-search process. Report recall@10 (and ideally recall@50) beside latency. Compare latency only at a similar recall target.
Workflow A: IDE symbol or code-snippet lookup
Send a code query vector and request the top 10 matching chunks. Start with vector-only search, then add a repository filter. Use a fixed query set that includes common and rare symbols. Report p50, p95 and p99 search latency, queries per second, recall@10, CPU use and resident memory. This test approximates interactive retrieval, but a production IDE should also measure network time, reranking and application overhead separately.
Workflow B: language and repository filtering
Repeat the search with a language filter and a repository filter at documented selectivities—for example, filters matching roughly 50%, 10% and 1% of the corpus. Generate those distributions deliberately and keep them identical across systems. Record filter-index settings and query plans. This reveals whether a database performs well for the filtered workload your developers actually use; a vector-only test cannot answer that question.
Workflow C: indexing while serving queries
Ingest a fixed batch of new chunks while sending a steady query stream. Measure indexing throughput, search p95/p99, resource contention and the time until new records become searchable. For a fair comparison, specify durability settings, batch size and whether each product acknowledges a write before or after indexing. If your application performs updates or deletes, include those operations and their effect on index maintenance.
How to report results
| Measure | What to publish | Why it matters |
|---|---|---|
| Search latency | p50, p95 and p99, with query count and concurrency | Tail latency often matters more to interactive tools than a single average. |
| Recall | Recall@10 or Recall@50 against exact-search ground truth | Faster approximate results may be less useful if relevant code is missed. |
| Capacity | Peak and steady-state RAM, disk use and index-build time | The raw vector size is not the full index footprint. |
| Throughput and contention | Queries per second during idle and concurrent ingestion | Production systems often search while data changes. |
| Configuration | Product release, topology, index parameters, filters and durability settings | Without these details, another team cannot reproduce or interpret the result. |
4. Pricing and Hidden Costs
Pricing verified as of Q4 2026: the self-hosted software paths for Qdrant, Milvus and pgvector are available without a per-vector license fee under their respective open-source licenses. Managed-service rates, cloud infrastructure rates and plan limits vary by provider, region and configuration; check the provider's current pricing page or calculator before committing. A free software license does not mean a zero-cost production deployment.
| Scenario | Core software | Infrastructure / managed service | AI and API costs |
|---|---|---|---|
| Solo Free | Self-hosted Qdrant, Milvus or PostgreSQL with pgvector: no software subscription fee for the open-source edition. | Potentially $0 additional cash cost on an existing development machine; production-grade cloud compute and storage are not free. | Embedding API cost is $0 if you use a locally run model. Otherwise calculate it from the chosen provider's current token or usage rate. The database itself does not require an AI add-on. |
| Solo Power User | Still no required license charge for the self-hosted open-source software. | Budget for a dedicated VM, persistent storage, backups and monitoring. Compare the total monthly cloud bill—not just the instance price—with a managed service. | For hosted embeddings, estimate input volume × provider rate, including re-embedding after model or chunking changes. Add reranking or code-generation API usage only if your application uses it. |
| Team | Self-hosted software can avoid per-seat database licensing, but engineering and on-call time remain costs. Managed plans may charge for capacity or usage. | Include replicas, backups, storage growth, network transfer, staging, observability, support and staff time. Obtain a quote or use the current official calculator for the intended region and topology. | Include embedding, reranking and any LLM calls as separate line items. These are workload costs shared by the database choices, not included in their open-source software fee. |
Official pricing and licensing references: Qdrant pricing and Qdrant license and source; Zilliz Cloud pricing and Milvus license and source; pgvector license and source and the chosen PostgreSQL provider's pricing page. Check each page for current terms and rates before deployment.
For a defensible total-cost comparison, use the same retention period and service objectives. Add compute, storage, backup, networking, managed-service charges, engineering time and embedding/API usage. Do not treat embedding generation as a database-specific expense unless the products use different models or workflows.
5. Pros, Cons and Who Should Choose What
Qdrant
- Pros: purpose-built vector search; a focused deployment model; supports HNSW and metadata-aware retrieval.
- Cons: adds a service and its operational lifecycle if your application is already centered on PostgreSQL; filtered workloads still need workload-specific validation.
- Choose it when: vector retrieval is a core service and you want to evaluate a dedicated engine without adopting a distributed architecture by default.
Milvus
- Pros: offers multiple deployment modes and index choices, making it a candidate for teams with evolving or larger-scale vector-search requirements.
- Cons: topology matters. Distributed deployment may require additional components and operations, and its latency should not be compared casually with another product's single-node configuration.
- Choose it when: you need to assess distributed vector infrastructure or its available indexing and managed-service options, and have the operational capacity to evaluate the intended setup.
pgvector
- Pros: keeps vectors and relational application data in PostgreSQL; enables SQL filters, joins and transactions; can reduce the number of systems to operate.
- Cons: vector search shares resources with database workloads, and index maintenance, query plans and database-level contention need attention. It is not automatically the best choice for every high-throughput vector workload.
- Choose it when: PostgreSQL is already your system of record, your SQL needs are important, and measurements show it meets your latency, recall and capacity targets.
Decision rule: first test pgvector if it removes a service from a PostgreSQL-based architecture. Test Qdrant and Milvus if vector search is independently important or the PostgreSQL test misses your service objectives. Select the least operationally complex option that meets your measured recall, tail-latency, throughput and availability requirements.
6. FAQ & Next Steps
Can one million code embeddings fit on a single machine?
The example dataset's raw vectors occupy about 2.86 GiB, but that is not a complete capacity estimate. HNSW structures, metadata, database overhead, caches, replicas and concurrent application use add to memory and storage needs. Measure peak resident memory and index size after loading your actual data, and leave headroom for operating-system and workload demands.
Which metric should decide the winner?
Use p95 or p99 latency at a documented recall target, with your real filters and expected concurrency. Also consider throughput during ingestion, index-build time, memory, durability and operating effort. A lower latency number at materially lower recall is not an equivalent result.
Next Steps & Related Reading
- Read Qdrant's official documentation before setting up its index and payload filters.
- Read Milvus documentation to choose and reproduce a deployment topology.
- Review pgvector documentation and examples for index options and SQL usage.
- Build a representative query set, pin the embedding model and data, then publish configuration and recall alongside latency. Re-run the test after major version, hardware or workload changes.
Editorial note: this article provides a reproducible methodology and architecture comparison, not measured head-to-head benchmark results. No latency winner is claimed.
Comments (0)