Qdrant vs pgvector performance

pgvector stays fast on small and medium corpora inside an existing PostgreSQL estate, while Qdrant's payload filtering, quantization and sharding matter once filters are selective and the corpus grows. Benchmark both on your own data before deciding.

On this page

Qdrant vs pgvector performance: which holds up as data grows

If your team already runs PostgreSQL and wants to know whether pgvector is fast enough as the corpus grows, the honest answer is that performance depends on corpus size, filter selectivity, the recall target you need and the hardware you run on. No single product wins across all of those. pgvector 0.8.7 supports exact nearest neighbor search by default and adds HNSW and IVFFlat approximate indexes, while Qdrant 1.19.2 is built around payload filtering, quantization and sharding. Your decision should rest on measurements from your own data, not on a general ranking.

The filter behavior matters most for a corpus with per-tenant, per-date or per-permission filters. The pgvector README states that with approximate indexes, filtering is applied after the index is scanned, so a selective WHERE clause can leave too few rows to return. Iterative index scans in strict or relaxed ordering modes can fetch more candidates when that happens, but you should test how much extra work they add at your selectivity. Qdrant's README describes JSON payload filtering on vectors, and its quantization claim of cutting RAM usage by up to 97% is the vendor's own figure. Neither project's numbers have been verified for your workload here.

No benchmark figures are supplied for this comparison, so the reader must measure. Build a representative sample of your corpus, run your real filter combinations, and record latency and recall at the top-k you will use in production, for each index type and for Qdrant with and without quantization. Repeat the test at two or three corpus sizes to see the curve, not a single point. Ask whether your recall target holds under filters, because a fast result that misses relevant documents is not a usable one. Keep the benchmark scripts, since they will be your baseline when you upgrade either system.

How each platform handles speed and recall

This table sets pgvector and Qdrant side by side on the parts of performance that change search speed and recall: indexes, filtering, memory, scale-out and iterative scans. Read each row as a question to answer with your own corpus, filters and hardware, since the supplied facts describe behavior but not benchmark results.

Performance factorpgvector (PostgreSQL extension)Qdrant (dedicated engine)
Index typesExact search by default, plus HNSW and IVFFlat approximate indexes. Confirm index parameters and recall for your version and data.Dense, sparse and hybrid search with JSON payload filtering. Confirm index configuration and recall targets in your own tests.
Filters and the indexFiltering is applied after the index is scanned, so selective filters can remove many candidates. Test filtered recall on realistic filter selectivity.Payload filtering is part of the engine's query path. Confirm how filtered queries perform on your payload fields and index settings.
Iterative scansIterative index scans in strict or relaxed ordering modes can fetch more results when filters remove too many. Confirm the mode and its latency cost.Not described in the supplied facts for pgvector-style iteration. Ask Qdrant engineers how to tune candidate counts for filtered search.
Quantization and memoryNo built-in quantization is described in the supplied facts. Plan RAM around vector dimensions, index type and the rest of the PostgreSQL workload.Built-in quantization that the README says cuts RAM usage by up to 97%. Measure the recall loss on your own embeddings before adopting it.
Vector size limitsIndexed vector columns support up to 2,000 dimensions. Check your embedding model's output size before choosing this path.Confirm the dimension limits for your Qdrant version and embedding model before sizing collections.
Sharding and scale-outA single PostgreSQL primary holds the vectors. Scaling reads uses hot standbys, and sharding vectors across nodes is not described in the supplied facts.Collections split into shards across nodes, with replication factor setting extra copies. Plan shard counts as multiples of the node count and test rebalancing by hand.
Resource isolationVector search shares CPU, memory and I/O with the transactional workload in the same database. Measure contention under peak load.Runs as its own service with separate storage and storage needs. Confirm block storage and SSD or NVMe requirements for your deployment.
Benchmark focusRun exact and HNSW or IVFFlat queries at your corpus size, with your filters and concurrency.Run the same queries against a single node and a multi-node layout, with the same quantization settings you plan to use.

Why filtered pgvector queries can return fewer results

pgvector's approximate indexes apply filters after the index has been scanned, so a selective WHERE clause can remove candidates the index already returned and leave you with fewer rows than your LIMIT asks for. The pgvector README notes this behavior for HNSW and IVFFlat. The index hands back its nearest neighbors first, and the planner then discards any that fail the predicate. If your workload filters by tenant, document status or a date range that matches a small share of rows, a plain query can silently return a short result set. Recall suffers in the same way, because true matches that fell outside the scanned candidate set never reach the filter at all.

pgvector's iterative index scans are the documented mitigation. In strict or relaxed ordering modes, the engine can keep scanning the index to fetch more candidates when a filter removes too many. Check the version you run, read the pgvector README for the exact setting names, and test the behavior with your own predicates. Relaxed ordering trades strict ordering guarantees for more complete results, so decide whether your application can accept results that are approximately ordered. Expect the extra scanning to add work per query, and measure that cost on production-sized filters before you rely on it.

Qdrant takes a different path. Its JSON payload filtering is evaluated as part of the vector search, so the filter condition is part of how candidates are gathered, not a step applied afterward. This matters most when filters are selective, when tenants or access groups must be isolated, or when a query must always return the requested number of matches. It matters less when your filters are broad and you can tolerate a few short result pages. Ask both systems the same selective question on your own data, and record returned counts and recall against an exact baseline rather than relying on either vendor's description.

What changes the result in practice

Qdrant and pgvector can return similar results on a small corpus and diverge sharply as data, filters and write load grow. The factors below decide which side of that line a given workload falls on, and each one is cheap to check before you commit to a service.

Corpus size and growth rate

Index build time, memory footprint and query latency all scale with the number of vectors, and pgvector's HNSW and IVFFlat indexes must fit alongside every other table in the same PostgreSQL instance. Qdrant keeps its collection in its own process and spreads it across shards when one node is no longer enough. Measure today's row count and project it over the period you plan to run. Check whether the index fits in memory at that size, since that is where latency changes most sharply.

Filter selectivity and filtered fields

The pgvector README notes that with approximate indexes, filtering is applied after the index is scanned, so a selective filter can leave too few candidates. Iterative index scans can fetch more rows, but each extra pass costs latency. Qdrant applies JSON payload filters during search. Benchmark your real filters, including the ones that match only a small share of rows, and count how many fields you filter on, because each added condition widens the gap in behavior.

Vector dimensionality

pgvector can index vector columns only up to 2,000 dimensions, although its vector type accepts up to 16,000. If your embedding model produces more dimensions than the index limit, pgvector falls back to exact search for that column or you must reduce dimensions before indexing. Qdrant has no equivalent indexing ceiling in the supplied facts, so confirm its limit against your model. Higher dimensions raise memory per vector and the cost of each distance calculation on both systems.

Quantization and RAM budget

Qdrant ships built-in quantization, which its README says can cut RAM usage by up to 97%. That matters when the full-precision index would not fit on the node you can afford. pgvector stores vectors at full precision in its standard types, and halfvec reduces size only by half of that precision. Decide the RAM budget first, then test recall after quantization on your own queries, because a smaller footprint is only useful if the top results still match.

Write and update rate

A table that receives constant inserts and updates forces index maintenance inside the same PostgreSQL instance that serves your transactional workload, so vacuum and index upkeep compete with application queries. Qdrant handles writes in its own service, but it still needs a replication factor and shard plan that match the write load. Measure sustained insert throughput and the search latency seen while writes run, not only read benchmarks on a static dataset.

Existing PostgreSQL version and tuning

A PostgreSQL estate already on a supported major version, with monitored autovacuum, replicas and connection pooling, can absorb a pgvector workload with less new tooling. Check which major version you run against the support dates, since version 14 reaches end of support on November 12, 2026. Ask your DBA how memory settings and index build parameters are tuned today. An under-tuned instance can make pgvector look slower than it is, and a well-tuned one can make the separate service unnecessary.

How to benchmark both before adding a service

This sequence gives you a like-for-like measurement of pgvector and Qdrant on your own data, so the decision to add a separate vector service rests on recall, latency and operating effort you have observed rather than on published numbers.

  1. Define the corpus and query set

    The data engineering or search owner exports a representative sample of production embeddings, their payload fields and a set of real user queries, with the embedding model and dimension fixed for the whole test. Include the metadata filters that the application actually applies, such as tenant, date range or access group, because filtering behavior is where the two systems differ most. The step is done when the team can state the vector count, dimension, payload fields and filter combinations in writing, and when the same sample can be loaded into both systems without transformation.

  2. Fix the recall target and the exact baseline

    The search owner and the application owner agree on a recall target and on the value of k that users see, then run exact nearest neighbor search on the sample to produce ground-truth results for every query. pgvector supports exact search by default, so the baseline can come from the same PostgreSQL instance, and it should be stored alongside the query set. The step is done when a fixed file of exact top-k results exists for each query and filter combination, and the target is written down before any approximate index is tuned.

  3. Build the pgvector indexes

    The database administrator creates a test table in a PostgreSQL version the team already supports, loads the sample, and builds an HNSW index and, separately, an IVFFlat index on the vector column with the distance operator used by the application. Keep vector dimensions within the 2,000 dimension limit for indexed columns, and record the index build time, index size and the parameters chosen for each index. Confirm how the filtered queries behave, since the pgvector README notes that filtering is applied after the index scan and that iterative index scans can fetch more results when filters remove too many. The step is done when both indexes are queryable with the filters and their settings are recorded.

  4. Build the matching Qdrant collection

    The platform engineer deploys a single Qdrant node in a configuration that matches the planned production setup, with authentication and TLS enabled as the security docs require for self-deployed instances, and creates a collection with the same vectors, distance metric and payload fields. Create payload indexes for the filter fields the application uses, and record the index settings and any quantization option under test. Because self-deployed Qdrant listens on all interfaces without authentication by default, confirm the network and access settings before loading data. The step is done when the collection holds the same vectors and payloads as the pgvector table and the filters return the same candidate sets.

  5. Run filtered and unfiltered queries at growing sizes

    The test operator loads the sample at several increasing sizes, such as a small slice, the expected corpus and a larger projection, and runs the full query set against both systems at each size, both with and without the production filters. Keep hardware, client concurrency and query order identical across runs, and repeat each run so warm-cache and cold-cache results are separated. The step is done when a table exists for each size showing results for pgvector HNSW, pgvector IVFFlat and Qdrant under identical conditions.

  6. Measure latency percentiles and recall against exact search

    The performance engineer records latency at median and tail percentiles for every run, and computes recall by comparing each approximate result set with the stored exact top-k from the baseline step. Plot latency and recall together for each system so that a speed gain that costs recall is visible, and flag any filter combination where results return fewer than k items. The step is done when the team can state, for each size and filter, which configuration meets the recall target and what latency it delivers.

  7. Test memory with and without quantization

    The platform engineer measures resident memory and storage for each configuration, first without compression, then with Qdrant's built-in quantization enabled and with the appropriate index settings on pgvector, and repeats the recall and latency measurements for each. Qdrant's README says its quantization cuts RAM usage by up to 97 percent, but the reduction on your vectors and recall target must be measured rather than assumed. The step is done when there is a memory and recall table for each configuration at the largest tested size.

  8. Record the operating effort of each setup

    The operations lead notes the work each setup required: installation, backup and restore, PostgreSQL minor and major upgrades, Qdrant storage requirements and the extra service to monitor, secure and back up if Qdrant is adopted. Compare what the existing database team already runs against what a second service would add, including authentication, TLS and audit settings. The step is done when the team has a written effort log per setup and a decision memo that pairs the performance results with the operating burden, and the figures in that memo come from the team's own environment and hardware.

When performance should decide the choice

Speed and recall should decide the choice only when pgvector's approximate indexes miss your recall target or your latency budget at your real corpus size, with your real filters. Before that point, the operational case for keeping vectors inside an existing PostgreSQL estate is usually stronger. The pgvector README notes that with HNSW and IVFFlat indexes, filtering is applied after the index scan, and iterative index scans can fetch more rows when filters remove too many. Run a benchmark that combines the filter selectivity your application actually uses (tenant, document type, date range) with the ef_search or probes settings you plan to deploy, and measure recall against exact search on the same data.

The case for a separate Qdrant service gets stronger when three conditions meet. The first is a large corpus with frequent, selective payload filters, where Qdrant's JSON payload filtering on vectors is designed to be part of the search path. The second is a need to shard across nodes: Qdrant's distributed mode uses Raft for cluster topology and splits collections into shards, with a replication factor that doubles storage at a factor of 2, and the docs recommend at least three nodes for production quorum. The third is memory pressure, where built-in quantization may matter. The Qdrant README says it can cut RAM usage by up to 97%, but that figure is the project's claim, so test the recall loss on your embeddings before you rely on it.

Durability, backups and replication need their own evaluation for each option, and they can outweigh raw speed in the decision. PostgreSQL offers hot standbys, synchronous and asynchronous replication, and point-in-time recovery, but automatic failover needs external tools. Qdrant needs block storage (not NFS or S3), and its self-deployed instances have no authentication configured by default. Once you have benchmark results, compare the operating burden of each path in the sibling comparison Qdrant vs pgvector, which covers when a dedicated vector database justifies another service and when pgvector is enough by corpus size and operations team.

Questions teams ask before benchmarking

How long does a Qdrant versus pgvector benchmark take, and what does it need from the team?

The duration depends on corpus size, the number of query patterns you test and how many people can prepare the data and read the results, so no fixed timeline applies. Plan for four work areas: a representative dataset with realistic payload fields, a test harness that replays the same queries against both systems, a plan for index build and tuning on each side, and a review of recall alongside latency. Each side needs someone who can run PostgreSQL or Qdrant under load and interpret EXPLAIN output or Qdrant metrics. Confirm the timeline with your own environment before committing, because hardware and data access drive it more than the tooling does.

Can our own engineers run the benchmark without outside help?

Yes, if at least one engineer can operate PostgreSQL and one can operate Qdrant, and the team can run a load generator against both in a comparable environment. The harder part is design: choosing filters that match production, setting recall targets, and keeping the index parameters fair between the two systems. Teams without that experience often compare a tuned index against a default one and draw the wrong conclusion. An outside partner can plan the scope in writing, build the harness and document the results, but the decision remains yours and your team will need to repeat the test as data grows.

What drives the cost of running Qdrant compared with extending PostgreSQL?

Cost comes from who runs each system and what it requires underneath. Extending PostgreSQL with pgvector adds work to an estate you may already operate, so the main cost is additional index maintenance, memory and storage tuning, and the staff time to watch query plans. Running Qdrant adds a separate service with its own storage, backups, upgrades and access control. The Qdrant installation docs say it needs block-level storage and cannot run on NFS or S3, and self-deployed instances need authentication configured before use. Ask any provider to price each component separately: infrastructure, licenses, operations hours and recurring upgrades.

Does Qdrant Cloud change the performance picture?

Qdrant Cloud changes who operates the cluster more than the core search behavior, since the open-source engine is the same Apache-2.0 product. Its tiers differ in what they include: the free single-node tier has 0.5 vCPU, 1 GB RAM and 4 GB disk, while Standard and Premium add uptime commitments and, at Premium, SSO and private VPC links. Your benchmark should therefore use the same node sizes you would pay for in either model. Confirm current tier limits and any cluster sizing rules with Qdrant directly, because a benchmark run on the free tier will not predict production latency.

What should a quote include if we hire help for the benchmark?

A quote should follow from a written scope that states the systems under test, the dataset and its size, the query set, the filters used, the recall and latency measures, and the deliverables. Ask for the hours or phases behind each line, the hardware and environment assumed, who provides infrastructure and access, and what is excluded, such as tuning beyond the agreed parameters or migration work. Ask how re-runs are priced if the dataset grows. DeployOpen plans fixed-scope engagements with scope, deliverables and timelines agreed in writing before work starts, and does not publish a price list, so the quote will reflect the agreed scope.

How do we keep benchmark results comparable across versions?

Pin the exact versions under test and record them with every result. For this comparison that means the Qdrant release (v1.19.2 was the latest GitHub release at the time of research), the pgvector release (0.8.7) and the PostgreSQL major version, which should be a supported one such as 18 or 17. Keep hardware, storage type, dataset, query set and index parameters identical, and rerun the suite after each minor upgrade. The PostgreSQL upgrading documentation notes that minor releases do not change the storage format, but major upgrades can change planner behavior, so treat any major upgrade as a new baseline. Store the harness in version control so every run is reproducible.

What running each one costs in effort

pgvector adds little new operational work if PostgreSQL is already run well, but the work it adds is recurring. PostgreSQL releases minor versions at least once every three months, and minor releases never change the internal storage format, so the routine task is replacing executables and restarting. Major versions arrive about once a year and each is supported for five years. The supported list in the PostgreSQL versioning policy is 18, 17, 16, 15 and 14, with 14 ending November 12, 2026, so a team on 14 has a dated decision to make. Major upgrades use pg_dumpall and restore, pg_upgrade, or logical replication, and the upgrade docs say logical replication allows only several seconds of downtime. Your existing DBA skills cover most of this, but you should confirm that the team has rehearsed a major upgrade on a copy of the database that holds vectors, including the HNSW index rebuild time, which grows with the corpus.

Qdrant's one-time work is in setup, and its recurring work is in cluster care. Qdrant needs block-level storage with a POSIX-compatible file system, SSD or NVMe is recommended, and it cannot run on NFS or S3, so the platform team must provision that storage before anything else. Self-deployed instances listen on all interfaces with no authentication by default, so enabling TLS and API keys (admin and read-only, or JWT-based per-collection permissions) is a required day-one task, not an optional hardening step. For production, the distributed deployment docs recommend at least three nodes so quorum survives a node failure, and a shard count that is a multiple of the node count. Each added node, shard change or replication factor change adds work that a managed service would otherwise handle, and the Helm chart lacks zero-downtime upgrades and automatic shard rebalancing. Ask any quote to separate the one-time build (storage, TLS, keys, cluster layout, backup with snapshots) from the recurring upgrade and on-call load.

How DeployOpen helps evaluate and implement

DeployOpen plans, implements, integrates, hardens, documents and supports self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks. For Qdrant vs pgvector performance, that means turning an open question about filtered search speed and recall into a benchmark your team can read and repeat on your own data.

How we scope

  • Agree in writing which corpora, query types and filter patterns the benchmark will cover
  • Define recall targets, latency measures and data growth steps before any test runs
  • Confirm the PostgreSQL version, hosting model and team skills that the comparison must reflect
  • Engagements are fixed-scope, with deliverables and timelines agreed before work starts

How we build

  • Load representative vectors and payloads into pgvector HNSW and IVFFlat and into Qdrant
  • Test filtered queries, quantization settings and shard layouts under the same hardware and data
  • Record recall and latency at each growth step so results can be compared across runs
  • Document configuration, index parameters and test scripts so results can be reproduced

How we hand over

  • Deliver a written findings report with the measured trade-offs and the conditions behind each result
  • Provide the benchmark scripts, configuration files and data generation steps to your team
  • Walk through the operating effort each option implies for your PostgreSQL or Qdrant estate
  • Record the decision inputs so a later move to a separate vector service can be planned

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers
  • Re-run the benchmark when Qdrant or pgvector releases change indexing or filtering behavior
  • Support upgrades and backups for whichever option your team adopts inside your infrastructure
  • Confirm retainer scope and response expectations in writing before support begins

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.