VectorChord: Postgres Vector Search With RaBitQ Compression
Scalable, fast, and disk-friendly vector search in Postgres, the successor of pgvecto.rs.
At a glance
- What is it?
- VectorChord is a PostgreSQL extension from TensorChord and the successor to pgvecto.rs. It keeps pgvector's types and syntax but replaces the index with RaBitQ quantization and autonomous reranking.
- Who is it for?
- Adopt VectorChord if you already run PostgreSQL, want pgvector-compatible types and syntax, and care about how many vectors fit on one machine, since the README's cost claims rest on RaBitQ compression rather than on extra hardware. Do not adopt it if you need a vector store outside PostgreSQL, or if you cannot accept an extension whose build depends on a pinned pgrx version and per-PostgreSQL feature flags.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 41 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What VectorChord changes about vector search in PostgreSQL
VectorChord (the extension is named vchord) is a PostgreSQL extension for vector search, and the README describes it as the successor of pgvecto.rs. The problem it targets is specific: storing and indexing many high-dimensional vectors on one machine without paying for a large amount of memory. The README frames the goal in cost terms, claiming that 400,000 vectors can be stored for one dollar, and that this is 6x more vectors than Pinecone's optimized storage and 26x more than pgvector/pgvecto.rs at the same price. Those are vendor figures from the project's own blog posts, not independent measurements, and they should be read as such.
The audience is teams that already run PostgreSQL and would rather not add a separate vector database. Because VectorChord depends on pgvector and reuses its vector representation, an existing application can point at the same column types and query operators. The README states that you can create a table with a vector column, insert rows, build a vchordrq index, and search with ORDER BY and LIMIT exactly as with pgvector. That compatibility is the adoption argument: the migration cost is closer to a reindex than to a rewrite.
It is worth being precise about what is not being claimed. The README does not say VectorChord returns exact nearest neighbors, and it does not say the index is a drop-in replacement for every pgvector index type. It says the extension is fully compatible with pgvector data types and syntax while providing defaults the project considers optimal. Compatibility of the interface is a narrower promise than compatibility of results, and the two should not be conflated when you are deciding whether an existing query plan will survive the switch.
RaBitQ compression, hierarchical K-means and autonomous reranking
The mechanism comes down to compression plus a correction step. VectorChord applies RaBitQ compression together with what the README calls autonomous reranking. RaBitQ is a published quantization method (Gao and Cheng Long, Proceedings of the ACM on Management of Data 2.3, 2024) that quantizes high-dimensional vectors with a theoretical error bound for approximate nearest neighbor search. Compression is what makes the storage numbers possible; reranking is what keeps recall acceptable after compression. The two have to be read together, because a compression ratio quoted without a recall figure says nothing about whether the results are usable.
The index build path is separate from the query path. The README attributes fast indexing to hierarchical K-means and optimized disk operations, and cites a blog post claiming 100 million vectors indexed in 20 minutes. Hierarchical K-means means the index is built as a tree of clusters rather than one flat list of centroids, which changes both build time and how a search descends through the structure. Memory growth during the build is controlled through dimensionality reduction and sampling, which the README says allows 1B-vector indexes to be built on machines with 128GB of memory in practice. The repository layout matches this description: Cargo.toml declares workspace crates named k_means, rabitq, vchordrq, vchordg, distance, simd and vector, so the quantization and clustering routines are separate libraries rather than one monolith. That split matters if you intend to read the code, because the quantization logic lives in its own crate.
VectorChord also ships native 4-bit (RaBitQ4) and 8-bit (RaBitQ8) vector types. The README claims RaBitQ8 maintains high precision with under 1 percent recall loss. Treat that as the project's own claim and measure it on your embeddings, since recall loss depends on the data and on the distance metric you query with.
Installing VectorChord with Docker and running a first search
The README recommends the Docker image for new users. The command below starts a PostgreSQL 18 container with the extension preinstalled, publishing port 5432 and setting the default password to mysecretpassword. The image tag pg18-v1.1.1 pairs the PostgreSQL major version with the extension version, and the README notes that tags must be chosen to match the extension version you intend to run.
docker run \
--name vectorchord-demo \
-e POSTGRES_PASSWORD=mysecretpassword \
-p 5432:5432 \
-d ghcr.io/tensorchord/vchord-postgres:pg18-v1.1.1Connect with psql using the default postgres user and the password you just set. The README gives this exact invocation.
psql -h localhost -p 5432 -U postgresInside the database, create the extension. The CASCADE keyword matters: VectorChord depends on pgvector, so the dependency is pulled in rather than failing on a missing extension.
CREATE EXTENSION IF NOT EXISTS vchord CASCADE;Then create a table with a three-dimensional vector column and insert a thousand random rows, following the README example.
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
INSERT INTO items (embedding) SELECT ARRAY[random(), random(), random()]::real[] FROM generate_series(1, 1000);The index type is vchordrq, not ivfflat or hnsw. The operator class vector_l2_ops selects L2 distance.
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops);Finally, query with the distance operator and a LIMIT. You should get the five nearest rows by L2 distance.
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;The README also points to a separate all-in-one image, tensorchord/vchord-suite:pg17-latest, which bundles VectorChord, VectorChord-bm25 and pg_tokenizer.rs. If you prefer not to use Docker, the README refers to the installation guide on docs.vectorchord.ai rather than giving build steps inline.
Building vchord from source and the PostgreSQL version matrix
Building from source is documented through the repository's Makefile rather than the README, and it is more involved than the Docker path. The Makefile shells out to pg_config to locate the PostgreSQL library and shared directories, then delegates the actual compile to an xtask crate. The install target copies the built artifacts into PKGLIBDIR and SHAREDIR, and the uninstall target removes files matching vchord.* from both. That means the build is tied to whichever pg_config is first on your PATH.
make build
make installThe Cargo.toml shows the version support explicitly: feature flags named pg14, pg15, pg16, pg17 and pg18 each forward to the corresponding pgrx feature, and pgrx is pinned to exactly version 0.17.0. There is no pg13 feature. The build also depends on rusqlite with the bundled feature, and on mimalloc for x86_64 and aarch64 on Linux and macOS. If you are packaging VectorChord for a distribution, those two dependencies are the ones most likely to conflict with system libraries, since both prefer to vendor their own C code. The workspace version in Cargo.toml is a placeholder, 0.0.0, so the release number comes from the build tooling rather than the manifest.
The practical consequence is that source builds are a packaging exercise, not a five-minute install. You need a working Rust toolchain, a pg_config for the exact major version you are targeting, and a decision about whether to link the system SQLite or accept the bundled copy. The Docker image sidesteps all of it, which is presumably why the README puts Docker first.
Where VectorChord is the wrong choice
The honest limitation is that VectorChord is an approximate index with a compression step, and the README's own framing admits this: RaBitQ8 is described as maintaining high precision with under 1 percent recall loss, which is a statement that recall is lost. If your application needs exact nearest neighbor results, or has a recall target the compression cannot meet, a compressed index is the wrong tool regardless of how fast it builds. The README links to a page on measuring recall, which is a signal that the project expects users to check this themselves rather than trust a default.
There is a second boundary. VectorChord is a PostgreSQL extension, so it inherits PostgreSQL's operational model: you upgrade it with the database, you back it up with the database, and you cannot use it from a non-PostgreSQL service without going through the database. Teams that want an independent vector service with its own scaling and deployment lifecycle will find the extension model constraining rather than convenient. The README does not document rollback of an index build, and it does not describe what happens to an in-progress build if the server restarts, so plan index builds as operations you can afford to repeat. The README also does not state a minimum PostgreSQL version in prose; the only version evidence in the repository is the pg14 through pg18 feature list in Cargo.toml.
A third case is worth naming. If your workload is small, in the thousands or low tens of thousands of vectors, the compression machinery buys you very little, and the extra index type and quantization choices add decisions you would not otherwise have to make. The cost argument in the README is aimed at large collections, and it is at that scale that the trade-offs it makes start to pay off.
VectorChord compared with pgvector
The comparison the README draws is against pgvector and pgvecto.rs, and it is a comparison of storage economics rather than of query syntax. Both projects store vectors in a PostgreSQL column and both answer ORDER BY ... LIMIT queries. The difference is what sits underneath. pgvector offers index types with their own tuning parameters, and the README's claim is that VectorChord provides optimal defaults out of the box with no complex parameter tuning needed. That is a real difference in day-to-day work: with VectorChord the knobs you touch are the index type, the operator class, and the quantization type, rather than a list of build and search parameters.
The second difference is the storage format. VectorChord adds 4-bit and 8-bit vector types on top of pgvector's representation, which is what enables the cost claims. If you are already on pgvector, the migration path the README describes is to create the extension with CASCADE and build a vchordrq index on the existing column, because the data types are shared. What you cannot do is keep both index types and expect the same recall characteristics, since they quantize differently. The README does not give a side-by-side recall comparison against pgvector, so the storage claim and the recall claim have to be evaluated separately on your own data.
Where pgvector retains an advantage is in the size of its parameter surface. If you have already tuned an ivfflat or hnsw index to a recall target and you know why each parameter is set the way it is, moving to a system that hides those parameters means giving up a lever you were using deliberately. VectorChord's defaults are a benefit when you have not tuned anything and a loss of control when you have.
Licence, releases and the cost of staying current
The repository's licence field is NOASSERTION, and the README carries two licence badges rather than one. That usually means the project is dual-licensed or splits licensing between components, but the repository metadata here does not state the terms, so read the LICENSE file and the licenses/ directory before you depend on it. If you are embedding VectorChord in a product, the licence question is the one to settle first, and it is not a question this article can answer for you.
The release cadence visible in the repository is modest: 1.0.0 on 2025-11-12, 1.1.0 on 2026-02-11, and 1.1.1 on 2026-02-28. The last push to the repository was on 2026-08-06, so work continues between releases. The upgrade cost is concentrated in two places. First, the extension version and the PostgreSQL major version are coupled through image tags and through the pg14 to pg18 feature flags, so a PostgreSQL major upgrade means rebuilding or switching images. Second, because VectorChord stores its index in PostgreSQL's own storage, an extension upgrade that changes the index format would require a reindex, and the README does not describe an online reindex path. Budget for index rebuild time, which the project's own figures put at 20 minutes for 100 million vectors under their test conditions.
Editorial conclusion
Adopt VectorChord if you already run PostgreSQL, want pgvector-compatible types and syntax, and care about how many vectors fit on one machine, since the README's cost claims rest on RaBitQ compression rather than on extra hardware. Do not adopt it if you need a vector store outside PostgreSQL, or if you cannot accept an extension whose build depends on a pinned pgrx version and per-PostgreSQL feature flags. Before committing, verify three things yourself: that your PostgreSQL major version is among pg14 to pg18, that the image tag you pull matches the extension version you intend to run, and that recall on your own embeddings matches what the quantization type promises. The README quotes under 1 percent recall loss for RaBitQ8, and that number is the one worth reproducing on your data.
Frequently asked questions
How does VectorChord compare with pgvector?
Both store vectors in a PostgreSQL column and answer ORDER BY ... LIMIT queries, and VectorChord depends on pgvector for the vector representation. The difference is the index: VectorChord uses vchordrq indexes with RaBitQ compression and autonomous reranking, and adds 4-bit and 8-bit vector types. The README claims 26x more vectors than pgvector/pgvecto.rs for the same price, which is a storage claim rather than a recall claim.
How do I install VectorChord with Docker?
The README recommends running the image ghcr.io/tensorchord/vchord-postgres:pg18-v1.1.1 with POSTGRES_PASSWORD set and port 5432 published, then connecting with psql as the postgres user. Inside the database you run CREATE EXTENSION IF NOT EXISTS vchord CASCADE. The README notes that image tags must match the extension version you intend to run.
Which PostgreSQL versions does VectorChord support?
Cargo.toml defines feature flags for pg14, pg15, pg16, pg17 and pg18, each forwarding to the matching pgrx feature. There is no pg13 feature. The README does not state a minimum version in prose, so the feature list is the version evidence in the repository.
What index type does VectorChord create?
The README example creates a vchordrq index, as in CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops). The operator class selects the distance function, here L2. The repository also contains crates named vchordg and vchordrq, and the README links to a page on graph indexes.
Community notes