<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee" -->

---
title: Benchmarking Vector search in six database engines
description: Six databases with built-in vector indexing were loaded with 990,000 OpenAI embeddings and benchmarked on HNSW index build time, storage, recall versus...
canonical: https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Benchmarking Vector search in six database engines | daily.dev
og:description: Six databases with built-in vector indexing were loaded with 990,000 OpenAI embeddings and benchmarked on HNSW index build time, storage, recall versus...
og:url: https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee
og:image: https://api.daily.dev/og/posts/q10k9J0ee.png
og:image:alt: Benchmarking Vector search in six database engines
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Benchmarking Vector search in six database engines

**[Percona Blog](https://daily.dev/sources/percona)** · 14 min read · 0 upvotes · 0 comments

## Summary

Six databases with built-in vector indexing were loaded with 990,000 OpenAI embeddings and benchmarked on HNSW index build time, storage, recall versus throughput, concurrency and index churn. Build time ranged from 1.9 minutes (Percona Search) to 6.7 hours (AliSQL), and index size from 3.9 GiB to 15.1 GiB. At 32 concurrent clients pgvector hit 21.7 times its single-client throughput, while the three InnoDB-based engines (MariaDB 11.8, MariaDB 12.3, AliSQL) stayed flat near 1x, a pattern the source does not attribute to a cause and that may partly reflect a harness-side interpreter lock. MariaDB 12.3 was fastest at recall 0.99 with 277 QPS. pgvector post-filters and stops, so recall fell to 0.1034 at 1% selectivity with its default settings, and the source did not measure iterative scan. Re-inserting into a populated index ran at 16 to 28 rows/s for the three InnoDB-based engines, against 41 to 76 rows/s for their initial load.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.percona.com/blog/benchmarking-vector-search-in-six-database-engines>

## Questions this post answers

### How long does it take to build an HNSW vector index for 1 million embeddings in pgvector versus MariaDB?

pgvector reached a queryable index in 40.9 minutes for 990,000 OpenAI embeddings at 1,536 dimensions, made up of 26.9 minutes of COPY plus 14.0 minutes of parallel build across 8 workers. MariaDB 11.8 took 3.6 hours and MariaDB 12.3 took 5.4 hours for the same corpus, because MHNSW updates the graph on every INSERT instead of building separately.

_Comparing index build times across databases on daily.dev helps you pick the right engine before committing hardware._

### Why doesn't pgvector throughput scale with concurrent clients in MySQL-based vector search engines like MariaDB?

MariaDB Connector/C holds the Python interpreter's global lock across its socket wait, so concurrent client threads queue on the lock rather than the database, making throughput look flat (about 148-210 QPS from 1 to 32 clients) even though the server itself isn't saturated. A smoke test at 4 clients returned 2,927 QPS at 0.325 ms median, confirming only about one query was actually in flight at a time.

_Understanding connector-level bottlenecks like this saves time debugging misleading concurrency benchmarks on daily.dev._

### How does pgvector handle filtered vector queries with low selectivity predicates?

pgvector's default post-filter walks the HNSW graph, collects ef_search candidate neighbors, then drops the ones failing the WHERE predicate, without retrying. At 1% selectivity this returned recall of just 0.1034, with only 1-2 rows returned instead of 10, while still reporting full speed with no warning. Iterative scan, available in pgvector 0.8, fixes this but isn't enabled by default.

_Knowing pgvector's filtered-query defaults keeps you from shipping a silent recall regression; track changes like this on daily.dev._

## Similar posts on daily.dev

- [Benchmarking vector indexes in MySQL with vector-dev-bench](https://daily.dev/posts/benchmarking-vector-indexes-in-mysql-with-vector-dev-bench-ja77stzet) · Planet MySQL · 0 upvotes · 0 comments
- [Benchmarking vector indexes](https://daily.dev/posts/benchmarking-vector-indexes-hch39inje) · Percona Blog · 1 upvotes · 1 comments
- [Vector Search in MySQL vs MariaDB: Look Beyond QPS](https://daily.dev/posts/vector-search-in-mysql-vs-mariadb-look-beyond-qps-prl0dcc4h) · lefred's blog \(Frédéric Descamps\) · 0 upvotes · 0 comments
- [From 48 Seconds to 130 Milliseconds: Vector Search in Tinybird](https://daily.dev/posts/from-48-seconds-to-130-milliseconds-vector-search-in-tinybird-7tg3oigsp) · Tinybird · 4 upvotes · 0 comments
- [Supercharge pgvector: 4x Faster HNSW with AlloyDB](https://daily.dev/posts/supercharge-pgvector-4x-faster-hnsw-with-alloydb-tkk8hpcfr) · Google Cloud · 0 upvotes · 0 comments

---

Tags: [#infrastructure](https://daily.dev/tags/infrastructure), [#postgresql](https://daily.dev/tags/postgresql), [#vector-search](https://daily.dev/tags/vector-search), [#pgvector](https://daily.dev/tags/pgvector)

[View this post on daily.dev](https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Benchmarking Vector search in six database engines","url":"https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee"},"datePublished":"2026-10-29T17:53:29.738Z","dateModified":"2026-10-29T18:06:38.890Z","description":"Six databases with built-in vector indexing were loaded with 990,000 OpenAI embeddings and benchmarked on HNSW index build time, storage, recall versus...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3821bb6446822e4964737b582bcf595c?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3821bb6446822e4964737b582bcf595c?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Percona Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Percona Blog","logo":"https://media.daily.dev/image/upload/s--Lb3XkBh3--/f_auto,q_auto/v1780213412/logos/percona?_a=BAMAMiWQ0","url":"https://daily.dev/sources/percona"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"infrastructure,postgresql,vector-search,pgvector","timeRequired":"PT14M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Percona Blog","item":"https://daily.dev/sources/percona"},{"@type":"ListItem","position":3,"name":"Benchmarking Vector search in six database engines"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/benchmarking-vector-search-in-six-database-engines-q10k9j0ee#faq","mainEntity":[{"@type":"Question","name":"How long does it take to build an HNSW vector index for 1 million embeddings in pgvector versus MariaDB?","acceptedAnswer":{"@type":"Answer","text":"pgvector reached a queryable index in 40.9 minutes for 990,000 OpenAI embeddings at 1,536 dimensions, made up of 26.9 minutes of COPY plus 14.0 minutes of parallel build across 8 workers. MariaDB 11.8 took 3.6 hours and MariaDB 12.3 took 5.4 hours for the same corpus, because MHNSW updates the graph on every INSERT instead of building separately. Comparing index build times across databases on daily.dev helps you pick the right engine before committing hardware."}},{"@type":"Question","name":"Why doesn't pgvector throughput scale with concurrent clients in MySQL-based vector search engines like MariaDB?","acceptedAnswer":{"@type":"Answer","text":"MariaDB Connector/C holds the Python interpreter's global lock across its socket wait, so concurrent client threads queue on the lock rather than the database, making throughput look flat (about 148-210 QPS from 1 to 32 clients) even though the server itself isn't saturated. A smoke test at 4 clients returned 2,927 QPS at 0.325 ms median, confirming only about one query was actually in flight at a time. Understanding connector-level bottlenecks like this saves time debugging misleading concurrency benchmarks on daily.dev."}},{"@type":"Question","name":"How does pgvector handle filtered vector queries with low selectivity predicates?","acceptedAnswer":{"@type":"Answer","text":"pgvector's default post-filter walks the HNSW graph, collects ef_search candidate neighbors, then drops the ones failing the WHERE predicate, without retrying. At 1% selectivity this returned recall of just 0.1034, with only 1-2 rows returned instead of 10, while still reporting full speed with no warning. Iterative scan, available in pgvector 0.8, fixes this but isn't enabled by default. Knowing pgvector's filtered-query defaults keeps you from shipping a silent recall regression; track changes like this on daily.dev."}}]}
```

