vchord is a PostgreSQL extension engineered for scalable, high-performance, and disk-friendly vector similarity search, serving as the successor to pgvecto.rs.
Website | Documentation | vchord_bm25 | pg_tokenizer | Blog | PGEXT | Releases | Issues | Upstream
To store vectors compactly while preserving recall, vchord combines RaBitQ1 quantization with inverted-file (vchordrq) and single-layer graph (vchordg) indexes plus in-database reranking. It stores up to 400,000 vectors per $1—roughly 6x more vectors per dollar than Pinecone's storage-optimized tier and 26x more than in-memory pgvector / pgvecto.rs HNSW indexes.
vchord is the core extension of the Vchord family maintained by PGSTY:
vchord(Docs / Meta): Scalable, high-performance, and disk-friendly vector similarity search.vchord_bm25(Docs / Meta): Native BM25 full-text ranking index (Block-WeakAnd).pg_tokenizer(Docs / Meta): Standalone multilingual text analyzer and vocabulary tokenizer.
- Cost-Effective Storage: Host 100M × 768-dim vectors on a single AWS
i4i.xlarge($247/mo)2, or scale to 1B × 96-dim vectors on ani7ie.6xlarge($2,246/mo)3 by keeping only compact centroids in RAM and streaming quantized lists from NVMe SSD. - Fast Index Construction: Build a 100M-vector index in ~20 minutes using hierarchical K-means4 or external index precomputation.
- Bounded Memory Growth: Control index build memory via dimensionality reduction and sampling5, enabling billion-scale index builds on 128 GB RAM nodes.
- Drop-In
pgvectorCompatibility: Directly indexespgvectordata types (vector,halfvec) and supports standard distance operators (<->,<#>,<=>) alongside multi-vector MaxSim (@#) retrieval. - Native Low-Bit Quantization Types: Provides native 4-bit (
rabitq4) and 8-bit (rabitq8) vector types with <1% recall loss onrabitq8.
ANN routing can trade small distance errors for speed. On ARM CPUs with FP16 and FHM, halfvec L2 centroid selection and graph pruning round differences to f16 and accumulate in f32, retrying in f32 if a difference overflows. Final reranking, sphere predicates, and the residual-quantization lower bounds that decide reranking order keep f32 differences and accumulation. Tune probes and search breadth against recall on your own data.
For full setup instructions (Debian/Ubuntu packages, PGXN, Kubernetes, and source builds), see the Installation Guide.
1. Install via Native Linux Packages (pig)
On EL 8/9/10, Debian 12/13, and Ubuntu 22.04/24.04 (PostgreSQL 14–18), you can install pre-built native packages from the Pigsty repository (see package matrix on pgext.cloud):
curl -fsSL https://repo.pigsty.io/pig | bash
pig repo add pgsql -u
pig ext add vchordThen add vchord to shared_preload_libraries and restart PostgreSQL:
psql -U postgres -c 'ALTER SYSTEM SET shared_preload_libraries = "vchord"'
sudo systemctl restart postgresqlFor a PostgreSQL 18 demo with upstream 1.1.1 preloaded (this image does not contain PGSTY 1.3.0):
docker run \
--name vchord-demo \
-e POSTGRES_PASSWORD=mysecretpassword \
-p 5432:5432 \
-d ghcr.io/tensorchord/vchord-postgres:pg18-v1.1.1Note
For hybrid vector + full-text search, use the all-in-one tensorchord/vchord-suite:pg18-latest image, which bundles vchord, vchord_bm25, and pg_tokenizer.
Connect to the instance with psql:
psql -h localhost -p 5432 -U postgresEnable the extension (this automatically enables pgvector as well):
CREATE EXTENSION IF NOT EXISTS vchord CASCADE;Create a table with a vector column and insert sample data:
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);Build a vchordrq index and run a nearest-neighbor query:
CREATE INDEX ON items USING vchordrq (embedding vector_l2_ops);
SELECT * FROM items ORDER BY embedding <-> '[3, 1, 2]' LIMIT 5;When tuning vchordrq, use one comma-separated probes value per level in
build.internal.lists. Each value must be in 1..=4294967295; empty entries
and spaces inside a value are invalid, and one trailing comma is ignored for
compatibility with 1.1.1. An empty string is valid for lists = [].
For vchordg, alpha must contain 1–8 ascending values starting with 1.0,
all below 2.0.
The 1.3.0 release provides Linux ZIP archives and Debian packages for PostgreSQL 14–18 on x86_64 and aarch64, built on Ubuntu 22.04 (glibc 2.35 or newer). Distribution repositories may update on a different schedule.
Install the matching library and SQL files, restart PostgreSQL, then run this in each database using the extension:
ALTER EXTENSION vchord UPDATE TO '1.3.0';Upgrades from 1.1.1 and 1.2.0 are tested. The on-disk format is unchanged. Read the release notes for cosine-index rebuilds, sampling permissions, and external-build compatibility.
The default vchordrq.epsilon remains 1.9 in 1.3.0. Higher values, such as
2.5, can improve recall and reduce distance-order inversions, at the cost of
more reranking. Measure recall and latency on your workload before increasing
it. Explicit session settings and per-index fallback values take precedence.
VACUUM repairs vchordg locally and reuses deleted space. It follows deleted
bridges when a neighbour list has spare capacity, with bounded expansion and
the existing pruning strategy. Arbitrary deletion patterns can still reduce
ANN recall. Keep autovacuum enabled, measure recall after large deletes, and
use REINDEX INDEX CONCURRENTLY index_name to rebuild from the table when
needed. Concurrent rebuilding allows reads and writes but needs extra disk
space and build resources; run it outside a transaction block. See
Graph maintenance.
New vchordrq vector pages and vchordg vertex pages are published with
their incoming links in one WAL record before entering the free-space map. This
closes concurrent insertion and recovery windows without changing the disk
format or adding a WAL flush per page. Full crash-safe reclamation of
maintenance pages is deferred: interrupted maintenance can still leave unused
pages, recoverable with REINDEX INDEX CONCURRENTLY.
Query sampling stays disabled by default. Reading samples requires superuser or
pg_read_all_stats; table ownership/SELECT cannot authorize other tenants’ query
vectors. Prewarm retains its table privilege checks. Samples are local,
nontransactional diagnostics. Index/database deletion cleans them up only after
ordinary transaction commit; rollback preserves them. Cleanup is best effort,
so a crash after commit or COMMIT PREPARED can leave unreachable samples.
DROP INDEX CONCURRENTLY can remove samples at an internal commit even if later cancelled.
Concurrent reindexing changes the index OID and resets its sample history.
External builds require build.external.table = 'schema.table'. Update legacy
unqualified options before any operation that rebuilds or replaces the index,
including REINDEX (with or without CONCURRENTLY), TRUNCATE, VACUUM FULL,
CLUSTER, column-type changes that rebuild indexes, and dump restore. Existing
queries remain usable until such an operation. Find external-build options with:
SELECT c.oid::regclass AS index_name, o.option_value
FROM pg_class AS c
JOIN pg_am AS am ON am.oid = c.relam
CROSS JOIN LATERAL pg_options_to_table(c.reloptions) AS o
WHERE am.amname = 'vchordrq'
AND o.option_name = 'options'
AND o.option_value LIKE '%external%';Review both dotted keys and [build.external] sections. Every external table must contain a schema and table
name, such as public.centroids. See Query sampling
and External builds.
PostgreSQL 19 is a prerelease. The pg19 feature and C API compatibility
code are available in main for development validation; official support
and packages remain PostgreSQL 14–18. RC1 source builds have been validated
on Linux x86_64 and macOS arm64 with Rust 1.99.1, pgrx 0.19.3, and
pgvector 0.8.7, including PostgreSQL assertions and the full SQL regression
suite.
Install pgvector for PostgreSQL 19, then build and install vchord against
the RC1 installation's pg_config:
git clone https://github.com/pgsty/vchord.git
cd vchord
PG_CONFIG=/path/to/pg19/bin/pg_config make build
make PG_CONFIG=/path/to/pg19/bin/pg_config install # use sudo if requiredAdd vchord to that server's shared_preload_libraries, restart it, and run
CREATE EXTENSION IF NOT EXISTS vchord CASCADE;. PostgreSQL 19 is not
included in the CI or release matrices. Formal release support will be
considered after PostgreSQL 19 GA and a fresh compatibility check.
The Check workflow is manually dispatched. Regular jobs retain the full
Rust and SQL suites, Clippy, and platform coverage. Valgrind on PostgreSQL 17/18
defaults to the two existing scan_abort.slt regressions (100-row fixtures),
covering scans, reranking, rescans, errors, cancellation, and resource cleanup.
The SQL step has a 20-minute timeout; the job including debug builds has a
90-minute timeout.
Enable full_valgrind explicitly to run the complete SQL suite under
Valgrind, with a five-hour SQL limit and a six-hour job limit. It can still time
out on slow runners; a timeout is incomplete coverage, not a pass. Valgrind
uses --leak-check=no, so this is not a full leak audit. Recovery and recorder
checks are described in devtools/README.md.
Full documentation is available at vchord.pgsty.com/docs/vchord:
- Getting Started
- Indexing & Querying
- Tuning & Operations
- Benchmarks & Use Cases
This software is licensed under the GNU Affero General Public License v3.0 (AGPLv3). You may use, modify, and distribute this software under the terms of the AGPLv3.
- Copyright (c) 2025-2026 TensorChord Inc.
- Copyright (c) 2026 PGSTY PTE. LTD.
- Maintained by Ruohang Feng @ PGSTY
Footnotes
-
Gao, Jianyang, and Cheng Long. "RaBitQ: Quantizing High-Dimensional Vectors with a Theoretical Error Bound for Approximate Nearest Neighbor Search." Proceedings of the ACM on Management of Data 2.3 (2024): 1–27. ↩
-
See How We Made 100M Vector Indexing in 20 Minutes Possible on PostgreSQL and Partitioning Tuning. ↩
