Vector DB benchmarks: Qdrant, Weaviate, Pinecone, pgvector under real load
Every vendor benchmark on this list is wrong about something. So is ours. We are publishing the methodology section anyway because the alternative is publishing numbers without it, which is the failure mode the agentic-stack press is most often guilty of.
Here is what we tested, how we tested, what we found, and what we would not bet on without further work.
Methodology
We benchmarked four vector stores against three workloads. The stores: Qdrant 1.10, Weaviate 1.25, Pinecone (serverless, us-east-1), and pgvector 0.7 on Postgres 16. The workloads:
- Read-heavy retrieval. 1M vectors, dim 1024, 95% reads / 5% writes, p99 latency over a 30-minute sustained run at 200 QPS, 500 QPS, and 1,500 QPS.
- Write-heavy ingest. 5M vectors ingested in two-hour windows, measured throughput and query latency during ingestion.
- Hybrid retrieval. Top-k=20 vector search combined with a metadata filter selecting 5% of the corpus, run at 200 QPS.
Hardware: matched-spec m6i.4xlarge for self-managed (Qdrant, Weaviate, pgvector), serverless tier for Pinecone with capacity sized for the workload. We are reporting p50 and p99 latency, throughput, and (for the self-managed) cost-per-million-queries at our instance rate. We are not reporting recall@k because we kept it constant across stores by tuning the relevant HNSW / IVF parameters to a target recall of 0.95 against a held-out ground-truth slice. The full configs are in the appendix at the end of this piece.
What this benchmark is not: a universal ranking, a fitness-for-your-stack assessment, or a vendor scoreboard. It is a snapshot of four stores under three workloads at a particular set of parameters. Your workload is not these workloads.
What we found
Read-heavy retrieval, p99 latency
| Store | 200 QPS | 500 QPS | 1,500 QPS |
|---|---|---|---|
| Qdrant 1.10 | 8 ms | 14 ms | 31 ms |
| Weaviate 1.25 | 11 ms | 19 ms | 42 ms |
| Pinecone serverless | 22 ms | 28 ms | 38 ms |
| pgvector 0.7 (HNSW) | 14 ms | 27 ms | 88 ms |
The story is unsurprising: purpose-built vector stores beat the general-purpose option on pure-read latency, and Qdrant edges out Weaviate at our config. Pinecone’s serverless tier is flat across the QPS range because of how the autoscaler smooths cost-of-going-up against latency-of-going-up; you pay more at low QPS for that smoothness, and less at high QPS. The pgvector number at 1,500 QPS includes the cost of Postgres’s planner choosing the HNSW index correctly, which it did consistently in our run after some ANALYZE work.
What the table does not show: pgvector’s p99 is much more bimodal than the others. The 88 ms is dragged up by a long tail of queries that fall on a different plan. If you can keep your query patterns regular, pgvector’s p99 sits much closer to 40 ms.
Write-heavy ingest, throughput
| Store | Ingest throughput (vec/sec) | Query p99 during ingest (200 QPS read) |
|---|---|---|
| Qdrant 1.10 | 18,400 | 21 ms |
| Weaviate 1.25 | 12,200 | 35 ms |
| Pinecone serverless | 25,000 (vendor-rated) | 27 ms |
| pgvector 0.7 (HNSW) | 5,800 | 71 ms |
Pinecone’s number is vendor-rated because we hit a quota wall before we could verify it ourselves. The qualitative finding holds even if the number is off by a third: Pinecone’s serverless tier is built for ingest, and the cost is the price.
pgvector’s ingest is slow because HNSW builds are expensive. The alternative is to use the IVFFlat index instead, which doubles ingest throughput but cuts read latency by 30%. There is no free lunch in the pgvector world; you are choosing a Pareto point on the ANN frontier.
Hybrid retrieval (vector + metadata filter)
The hybrid workload is the most realistic for production agentic systems. Real queries almost always carry a tenant id, a date range, or a category filter alongside the vector search.
| Store | Hybrid p99 | Filter strategy |
|---|---|---|
| Qdrant 1.10 | 18 ms | Payload index, pre-filter |
| Weaviate 1.25 | 24 ms | Inverted index, pre-filter |
| Pinecone serverless | 41 ms | Metadata filter post-merge |
| pgvector 0.7 | 23 ms | Standard B-tree + HNSW combined |
This is the workload where pgvector earns its keep. Postgres knows how to combine a B-tree filter and an HNSW index because it knows how to combine indexes in general. The other stores have to special-case the hybrid path, and Pinecone’s serverless tier post-filters after the vector merge, which is the most expensive way to do it.
If your workload is hybrid-dominant, pgvector and Qdrant are the picks. If it is pure-vector, Qdrant is the pick.
What changes under real production patterns
The benchmark above is a steady-state benchmark. Real production traffic is not steady-state. Three patterns warp the rankings:
- Bursty ingest with read SLO. If you batch-insert once a day and need to keep p99 read latency under 50 ms, Pinecone wins because its serverless architecture absorbs the burst without affecting reads. The self-managed stores all degrade under burst. pgvector degrades the most.
- Multi-tenant with tenant-scoped filtering. All four stores can do this. Qdrant’s payload-index approach is the fastest of the four, but Pinecone’s namespace primitive is the easiest to reason about operationally. We have seen teams pick Pinecone primarily for the tenancy story.
- Aggressive recall requirements (recall@5 ≥ 0.98). This is where the tuning matters more than the store. We pushed every store to 0.98 and Weaviate held the latency line best at that recall, with Qdrant slightly behind. pgvector fell off a cliff above 0.96. Pinecone is a black box on tuning, so we cannot say what is happening internally; the observed latency at 0.98 was 65 ms p99 against our workload.
What we would change about this benchmark
Three things we will redo in the next pass:
- Recall variance. We held recall constant. We did not measure recall variance across query types. In production, recall is not uniform; some query types retrieve consistently and others retrieve poorly. The store choice could be the same across recall mean and different across recall variance.
- Cold-start cost. We measured steady-state. We did not measure cold-start latency after an idle window. Pinecone’s serverless tier has a real cold-start cost. The self-managed stores do not.
- Schema migrations. We did not test reindexing under load. The stores differ meaningfully on this. We will report next quarter.
Decision tree
If you want a single sentence per architecture:
- You are pre-product-market-fit and want one less moving piece. pgvector. Run it on the Postgres you already run.
- You have a single vector-search workload, high QPS, and care about p99. Qdrant.
- Your workload is heavily hybrid (vector + metadata filter). pgvector if you already have Postgres, Qdrant if not.
- You have multi-tenant requirements and want the operational story to be small. Pinecone serverless.
- You want flexibility on the schema side and your traffic is moderate. Weaviate.
We do not have a recommendation that holds across all architectures, and we do not believe the publications that do. Pick the store against your workload.
Appendix: configs
Qdrant: HNSW, m=16, ef_construct=128, ef_search=64, payload index on the filter field.
Weaviate: HNSW, ef=128, efConstruction=128, maxConnections=32, inverted index on the filter field.
pgvector: HNSW (lists=200), filter B-tree.
Pinecone: serverless tier, default config; we did not tune.
Full eval set, ground-truth, and query trace available on request from the editorial inbox.
— The Editorial Team