October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Fix Slow pgvector Similarity Queries in PostgreSQL

Use the actual PostgreSQL plan to find why pgvector similarity search is slow, then choose measured fixes for index choice, recall, filtered results, and memory.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start with the plan, not another index or a larger search setting. Run EXPLAIN (ANALYZE, BUFFERS) on the slow query, then check whether PostgreSQL uses the intended vector index, whether the distance operator matches that index’s operator class, and how many rows a filter removes. The right fix depends on what the plan shows—and, for approximate search, on how much recall you can trade for latency.

Why is my pgvector query slow?

Inspect the exact query that is slow, including its filters, ordering, and limit. PostgreSQL’s EXPLAIN output compares estimated and actual row counts; ANALYZE runs the query and reports actual execution details, while BUFFERS shows buffer activity. pgvector recommends this form for performance troubleshooting.

As an Amazon Associate I earn from qualifying purchases.

EXPLAIN (ANALYZE, BUFFERS)
SELECT id
FROM items
ORDER BY embedding <-> '[0.1, 0.2, 0.3]'::vector
LIMIT 10;

In the plan, find the scan and sort nodes, whether the intended index appears, actual versus estimated rows, rows removed by filters, and where execution time and buffer activity accumulate. A slow query does not by itself prove that an index is missing: the plan may be doing exact search, using a different path because of selectivity, or scanning many approximate candidates before filters leave enough results.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the operator and operator class

The distance operator in ORDER BY must correspond to the operator class used to build the vector index. pgvector has separate operator classes for L2 distance, inner product, cosine distance, and other distance functions. If an application needs multiple distance functions, create an index for each one it uses.

Distance used in the query Matching pgvector operator class
L2 distance, <-> vector_l2_ops
Cosine distance, <=> vector_cosine_ops
Negative inner product, <#> vector_ip_ops

For example, an HNSW index for L2 distance can be created with CREATE INDEX ON items USING hnsw (embedding vector_l2_ops);. Confirm that the application orders by the same distance operator. A mismatched operator and operator class can prevent the intended nearest-neighbor index path.

Should you use exact search, HNSW, or IVFFlat?

pgvector uses exact nearest-neighbor search by default; it provides perfect recall, but may take longer as the candidate set grows. HNSW and IVFFlat are approximate alternatives: they trade some recall for speed. Compare them on representative data and queries rather than assuming an index or setting will improve your workload.

Approach Recall and query trade-off Build and memory profile Useful starting points
Exact search Perfect recall; can be a good fit when the filtered subset is small or perfect recall is required. No approximate vector index is needed for the exact search itself. A conventional index on filter columns may help narrow the subset. For exact search without a vector index, pgvector says raising max_parallel_workers_per_gather can improve speed. For unit-normalized vectors, its documentation recommends inner product for best performance.
HNSW Generally stronger speed/recall trade-off than IVFFlat; raising hnsw.ef_search generally improves recall at a query-time cost. Slower index builds and higher memory use than IVFFlat. Can be created before the table contains data. Documented defaults: m = 16, ef_construction = 64, and hnsw.ef_search = 40.
IVFFlat Generally lower query performance in the speed/recall trade-off than HNSW; increasing ivfflat.probes improves recall at a speed cost. Faster builds and lower memory use than HNSW. Build after representative data is present. Project heuristics: lists around rows / 1,000 up to one million rows, and around the square root of row count above that; start probes around the square root of lists. These are starting points, not universal optima.

Measure query latency, recall, index build time, memory footprint, filtered-result yield, and the impact of writes and maintenance. Compare approximate results with an exact-search baseline on representative queries so you can see which neighbors are lost; adding an approximate index can change the returned neighbors.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Tune HNSW per query

Test higher search breadth in a transaction so the change applies only to that transaction:

BEGIN;
SET LOCAL hnsw.ef_search = 100;
SELECT id
FROM items
ORDER BY embedding <-> '[0.1, 0.2, 0.3]'::vector
LIMIT 10;
COMMIT;

Compare the plan, latency, and recall with the default ef_search of 40. A higher value generally examines more candidates and can improve recall, but it may also increase query work.

Choose IVFFlat lists and probes from your data

IVFFlat works best when built after representative rows have been loaded. Use the project’s row-count heuristics only to pick an initial lists value, then test ivfflat.probes against actual query latency and recall. Increasing probes searches more lists and generally improves recall at a speed cost; neither heuristic guarantees the best setting for a particular dataset.

Why does a filtered vector query return too few results?

With an approximate index, pgvector applies metadata filters after scanning the ANN index. The project’s example illustrates the effect: if a filter matches 10% of rows and HNSW uses its default ef_search of 40, only four matching rows are expected on average. A query asking for more than that can return too few results, even though the unfiltered ANN scan appears to work.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use the plan to see whether the filter is selective and how many scanned rows it removes. Then choose a remedy based on how many distinct filter values you have and how much extra search work is acceptable.

Use iterative scans when available

Iterative index scans were introduced in pgvector 0.8.0. In pgvector 0.8.0 and later, they let an approximate scan continue until it finds enough matching rows or reaches a configured limit. Strict ordering preserves distance order; relaxed ordering can return results slightly out of order and may improve recall.

BEGIN;
SET LOCAL hnsw.iterative_scan = strict_order;
SELECT id
FROM items
WHERE category_id = 42
ORDER BY embedding <-> '[0.1, 0.2, 0.3]'::vector
LIMIT 10;
COMMIT;

For HNSW, iterative scans have a documented hnsw.max_scan_tuples default of 20,000 and hnsw.scan_mem_multiplier default of 1. For IVFFlat, ivfflat.max_probes bounds probes. Raising these limits can require more work or memory; test the resulting plan and recall instead of raising them without measurement.

If you use relaxed ordering but need strict final distance order, pgvector documents sorting the materialized results afterward. Its example requires distance + 0 on PostgreSQL 17 and later:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
WITH relaxed_results AS MATERIALIZED (
  SELECT id, embedding <-> '[0.1, 0.2, 0.3]'::vector AS distance
  FROM items
  WHERE category_id = 42
  ORDER BY embedding <-> '[0.1, 0.2, 0.3]'::vector
  LIMIT 10
)
SELECT id, distance
FROM relaxed_results
ORDER BY distance + 0;

Use filter indexes, partial indexes, or partitioning

For a highly selective filter, a conventional index on the filter column may let PostgreSQL find the matching subset and perform exact distance ordering within it. For queries filtering on several columns, consider an appropriate multicolumn index. This can be preferable to making an approximate scan search much farther.

  • Few distinct filter values: consider partial vector indexes for the relevant values.
  • Many distinct filter values: consider partitioning so a query searches a smaller relevant portion of the data.
  • Tenant isolation: pgvector recommends list partitioning or separate tables. A shared approximate index can let one tenant’s vectors affect another tenant’s query speed and recall.

For a distance threshold, pgvector documents placing the threshold outside a materialized nearest-results CTE while keeping other filters inside it. This separates candidate selection from threshold filtering.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How should memory, loading, and index maintenance affect the fix?

If index size or memory pressure is the bottleneck, pgvector documents halfvec for a smaller working set and binary quantization with reranking for smaller indexes at scale. These approaches can change accuracy, so compare recall as well as resource use before adopting them.

  • Bulk loading: use COPY for bulk data, then add indexes after the initial load for best performance.
  • Writes during index creation: CREATE INDEX CONCURRENTLY avoids blocking writes, though it still has operational constraints.
  • HNSW vacuuming: vacuuming an HNSW index can take time; pgvector suggests reindexing concurrently before vacuuming to speed that process.

If query and index changes are not enough at your scale, pgvector names PostgreSQL replicas, Citus, and PgDog as possible scaling approaches. Treat infrastructure changes as a separate decision and benchmark end-to-end workload behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which pgvector version do you have?

Check the installed extension version before relying on release-specific features:

SELECT extversion
FROM pg_extension
WHERE extname = 'vector';

The pgvector changelog lists version 0.8.7, dated 2026-10-01, and records an IVFFlat index-build buffer-overflow fix. It lists version 0.8.0, dated 2024-10-30, as introducing iterative index scans and improvements to filtering cost estimation and HNSW query performance. Those release notes do not establish that upgrading will make a particular workload faster; verify compatibility and measure the workload after any upgrade.

A practical order for troubleshooting

  1. Capture the actual slow query and run EXPLAIN (ANALYZE, BUFFERS).
  2. Check estimated versus actual rows, index usage, rows removed by filters, and where time and buffer activity accumulate.
  3. Verify the query’s distance operator matches the vector index’s operator class.
  4. Decide whether exact search is acceptable or whether the workload warrants approximate search.
  5. For filtered ANN queries, test iterative scans and their limits; if filter selectivity or tenant boundaries call for it, test filter indexes, partial indexes, or partitioning.
  6. Compare latency, recall, result yield, memory, build time, and maintenance cost on representative data before keeping the change.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.