Build1 distinct publisher3 min readUpdated
HNSW indexing runs inside the SQL engine, so there is no second service and no network hop. There is also no index persistence unless you turn on an experimental flag.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
DuckDB ships an official extension, `vss`, that adds HNSW-based approximate nearest neighbour search directly on top of its native fixed-size `ARRAY` type [1]. That collapses a common two-system RAG architecture into one process, and the extension is unusually candid about the conditions under which that collapse is safe [15][17].
The argument, as set out in a practical guide published on dev.to, is that teams already using DuckDB for analytics or a lightweight retrieval pipeline probably do not need Pinecone, Qdrant, Milvus or pgvector as an extra moving part [2]. The mechanism is HNSW, the same graph-based algorithm the guide says most production vector search engines use [3], and because it is embedded there is no separate service to run and no network hop [4].
The workflow is short. `INSTALL vss; LOAD vss;` follows DuckDB's usual extension pattern [5]. You declare the embedding column with its dimensionality fixed at table-creation time, because `ARRAY` is size-constrained, unlike the variable-length `LIST` type [6][7], then build the index with `CREATE INDEX ... USING HNSW` [8]. After that, DuckDB routes any query that orders by a supported distance function against a constant vector and applies a `LIMIT` through the index rather than a full scan [9]. You confirm it with `EXPLAIN` and look for an `HNSW_INDEX_SCAN` node in the plan [10]. The overloaded `min_by(col, arg, n)` aggregate is also index-accelerated and returns the full matched row as a struct [11].
Metric handling is reasonable. The default is `l2sq`, matching `array_distance` [12]; cosine is selected at index-creation time with `WITH (metric = 'cosine')` [13], which the guide calls the natural choice for embeddings from OpenAI or Sentence-Transformers [14]. You can build several indexes on one column with different metrics, though each HNSW index covers exactly one column [15]. `ef_search` can be overridden per connection with `SET hnsw_ef_search`, so accuracy can be traded against latency without a rebuild [16].
Now the part that decides whether this is a real substitution. By default, HNSW indexes can only be created on in-memory databases; persisting one into a disk-backed `.duckdb` file requires setting `hnsw_enable_experimental_persistence` [17][18]. The flag exists because WAL recovery is not yet fully implemented for custom extension indexes, so a crash or kill with uncommitted changes to an HNSW-indexed table can corrupt the index or lose data, and the documentation says this is not recommended for production [19][20]. Read those two facts together and the production-safe configuration is one where the index does not survive a process restart [1]. Recovery from an unexpected shutdown is possible, but it is a manual sequence: start DuckDB separately, load `vss`, and `ATTACH` the database file before WAL replay runs [21]. With persistence on, the whole index is serialised to disk at every checkpoint with no incremental updates, and deserialised back into memory on next access [22].
So the honest boundary is not query semantics, it is durability and working-set size. If your corpus is rebuilt on startup, or small enough to sit in memory and be re-embedded cheaply, the second database is genuinely surplus [2][17]. If you need an index that survives a hard kill, or one large enough that full serialisation per checkpoint hurts, the extension currently tells you so itself [19][22].
Worth watching: whether WAL recovery for custom extension indexes lands and lets the persistence flag lose the word experimental [19], whether checkpoint serialisation becomes incremental [22], and whether `vss` graduates from experimental core extension status at all [1].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The guide argues that if you are already using DuckDB for analytics or building a lightweight RAG pipeline, there is a good chance you do not need another moving part such as Pinecone, Qdrant, Milvus or pgvector.
DuckDB ships an official, experimental core extension called vss that adds HNSW-based approximate nearest neighbour indexing to accelerate similarity search over DuckDB's fixed-size ARRAY columns.
vss implements HNSW (Hierarchical Navigable Small Worlds), described in the guide as the same graph-based ANN algorithm used by most production vector search engines.
Because the extension is embedded, there is no separate service to run, no network hop and no extra infrastructure to operate; the vector index lives in the same process as the rest of the SQL engine.
Installation follows DuckDB's usual extension pattern: INSTALL vss; LOAD vss;
The dimensionality of the vector column must be fixed at table-creation time, for example a column declared FLOAT[3].
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Specific and internally consistent, but single-sourced and unmeasured
The technical claims are unusually concrete for a single source: exact statements, flag names, plan node names and syntax that a reader can execute and falsify, and the limits are attributed to DuckDB's own documentation. But the cluster has exactly one publisher, no independent corroboration, no cited DuckDB version, and no quantitative results of any kind, so the ceiling is capped well below high confidence.
No adoption evidence supplied
The cluster contains no release dates, deployments, usage disclosures, benchmark runs or user counts for the vss extension. The only signal is that the extension exists and is documented, which does not support an adoption measurement.
Mildly overstated framing, self-corrected in the body
The framing that a DuckDB user probably does not need Pinecone, Qdrant, Milvus or pgvector is a displacement claim carried entirely by architectural reasoning: there are no benchmarks, no scale data and no adoption evidence in the cluster, and the feature is experimental with persistence documented as non-production. That pushes the gap positive. It stays small because the same article surfaces the durability constraint explicitly, quotes the upstream non-production recommendation, and tells readers to rebuild the index on startup rather than claiming parity with a dedicated vector store.
No disclosure or affiliation evidence
The cluster provides no information about author affiliation, sponsorship, vendor relationships, funding or commercial interest in DuckDB or in any of the named vector databases. Assigning an incentive score would require inferring facts the supplied material does not contain.
Moderate on mechanics, low on impact
Confidence in the mechanical and limitation claims is reasonably high because they are specific, falsifiable and partly attributed to upstream documentation. Confidence in the broader story, that vss removes a database from RAG stacks, is low: one publisher, zero adoption evidence, zero benchmarks, and no incentive visibility. The blended result is moderate.
build
Six pragmas and a context manager: the vector store that fits in 2GB of RAM1 distinct publisher
build
DuckDB is growing a server, and someone on your team will have to run it1 distinct publisher
build
Semantic code search over a monorepo is now a plumbing job, and the plumbing is the hard part1 distinct publisher
build
Your RAG Cannot Find SKU-4471, And A Bigger Embedding Model Will Not Help1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 15, 2026