English | 中文
VexDB-Lite is a vector similarity search engine for PostgreSQL, DuckDB, and SQLite. The backends share the same graph index algorithm, SIMD distance dispatch, and PQ/RaBitQ quantization kernels.
See vexdb_duckdb/README.md for the DuckDB extension docs.
This root README is a project-level overview and build guide.
Latest release: v0.0.17
- PostgreSQL 16–19 packages for Linux x86_64 and AArch64
- DuckDB v1.5.2 packages for Linux x86_64 and AArch64
- SQLite packages for Linux, macOS, iOS, Android, and WASM
SHA256SUMS.txtcovering all 30 release archives
Current functionality:
floatvector(N)type- Distance functions and operators:
l2_distance(<->)cosine_distance(<=>)inner_product(use<~>for negative inner product / MIPS)
- Scalar helpers:
vector_dims(),vector_norm(),l2_normalize(),vexdb_index_info() CREATE INDEX ... USING vexdb_graph- Index options:
m,ef_construction,parallel_workers(parallel build),quantizer(pq/rabitq),pq_m, andmemory_mode - PQ and RaBitQ code-only storage;
memory_mode='compact'makes quantizer activation mandatory - Optimizer rewrite into an ANN Index Scan
- Shared-memory vector buffer cache and parallel index build
- Runtime settings:
vexdb.ef_search,vexdb.vec_architecture
Current functionality:
GRAPH_INDEXonFLOAT[N]vector columns- Distance functions and operators:
l2_distance(<->)cosine_distance(<=>)inner_product(use<~>for negative inner product / MIPS)
Note:
<#>is unavailable in DuckDB (#clashes with its comment syntax); use<~>for negative inner product — same meaning as in PG. - Scalar helpers:
vector_dims(),l2_normalize(),vexdb_version(),vexdb_index_info() CREATE INDEX ... USING GRAPH_INDEX (vec [, metadata...])with metadata filtering- Index options:
m,ef_construction,parallel_workers(parallel build),quantizer(pq/rabitq) andpq_m - Both PQ and RaBitQ support
memory_mode='compact'; compact RaBitQ still traverses the graph using quantized codes - Optimizer rewrite into
VEXDB_INDEX_SCAN - Vector buffer cache and parallel index build
- Runtime settings:
vexdb_ef_search,vexdb_brute_force_threshold,vexdb_pq_search_mode,vexdb_pq_refine_k_factor
See vexdb_sqlite/README.md for the full API and build guide. Current functionality:
GRAPH_INDEXvirtual tables with shadow-table persistence- L2, cosine, and inner-product search with JSON or float32 BLOB vectors
- Incremental insert, update, delete, transaction rollback, and reopen recovery
- Metadata filtering,
LIMITpushdown, and parallel graph construction - PQ and RaBitQ in full or compact memory mode
- Loadable desktop extension plus static registration for iOS, Android, and WASM
| Category | Feature | Description | PGVector | VexDB-Lite (open-source) | VexDB (commercial) |
|---|---|---|---|---|---|
| Graph Index | graph_index | A fully self-developed high-performance graph index that merges the advantages of various graph indexes and works seamlessly across all scenarios. | ❌ | ✅ | ✅ |
| Distance | Distance function dispatch | Inlined distance functions, compile-time optimized | ❌ | ✅ | ✅ |
| Cache | vector buffer | General vector cache, all scenarios | ❌ | ✅ | ✅ |
| Cache | bulk buffer | Full in-memory vector cache for max throughput | ❌ | ❌ | ✅ |
| Cache | Async I/O cache | Accelerated disk-to-cache reads under memory pressure | ❌ | ❌ | ✅ |
| Data types | floatvector | Standard float32 vector type | ✅ | ✅ | ✅ |
| Data types | halfvector | Float16 vector type | ✅ | 🟡 | ✅ |
| Data types | int8vector | Int8 vector type | ❌ | 🟡 | ✅ |
| Quantization | PQ quantization | Maximum compression, QPS close to raw vectors | ❌ | 🟡 | ✅ |
| Quantization | RaBitQ quantization | Quantized graph traversal with code-only index storage | ❌ | ✅ | ✅ |
| Quantization | Auto quantization | Background auto-enable, supports empty-table index build | ❌ | ❌ | ✅ |
| Graph index enhancement | Async insert | Fast ingestion for write-heavy workloads | ❌ | ❌ | ✅ |
| Graph index enhancement | Graph sharding | Large-scale vectors on small-memory machines | ❌ | ❌ | ✅ |
| Graph index enhancement | Subgraph index build | Continue using memory for index building even in low-memory scenarios to accelerate build speed | ❌ | ❌ | ✅ |
| HA | Primary-replica HA | Synchronous replication and backup restore | ✅ | ❌ | ✅ |
| Maintenance | Parallel vacuum | Parallel index cleanup and reclaim | ❌ | ❌ | ✅ |
| Category | Feature | Description | DuckDB VSS | VexDB-Lite (vexdb_lite) |
|---|---|---|---|---|
| Index | Graph index | VSS: HNSW; VexDB: graph_index (self-developed hybrid) | ✅ | ✅ |
| Distance | SIMD dispatch | Inlined distance functions, compile-time optimized | ❌ | ✅ |
| Quantization | PQ | Vector compression for memory-constrained scenarios | ❌ | ✅ |
| Quantization | RaBitQ | Shared quantized graph traversal with optional compact index-side storage | ❌ | ✅ |
| Cache | Buffer management | Disk-to-memory vector caching | ❌ | ✅ |
| Maintenance | Index compaction | Reclaim space from soft-deleted entries | ✅ | ❌ |
| Search | Filtered ANN search | WHERE filter with automatic oversampling | ❌ | ✅ |
| Persistence | Disk-backed index | Index survives database restart without rebuild | ✅† | ✅ |
† VSS persistence is experimental — WAL recovery is not implemented, unexpected shutdowns may cause index corruption. VexDB-Lite persists via DuckDB's standard serialization.
✅ Supported · 🟡 Coming soon · ❌ Not included in open-source edition
CREATE EXTENSION vexdb_lite;
CREATE TABLE items (
id BIGSERIAL PRIMARY KEY,
vec floatvector(128)
);
INSERT INTO items (vec) VALUES
('[0.10, 0.20, 0.30]'),
('[0.40, 0.50, 0.60]');CREATE INDEX idx_items_vec
ON items
USING vexdb_graph (vec floatvector_l2_ops)
WITH (
m = 16,
ef_construction = 64
);PQ reduces vector storage by encoding indexed vectors with a trained codebook:
SET maintenance_work_mem = '2GB'; -- required; low memory falls back to a plain graph index
CREATE INDEX idx_pq
ON items
USING vexdb_graph (vec floatvector_l2_ops)
WITH (quantizer = 'pq', pq_m = 4);Current v1 behavior:
- If there are fewer than 256 training samples, or the memory build budget is too low, PQ falls back to a plain graph index with a NOTICE.
- PQ indexes support post-build
INSERT/UPDATE/DELETE; new vectors are encoded with the trained codebook. - For
parallel_workers > 0, PQ training still runs in the leader process; PG parallel workers only participate in the disk-build phase.
Check the active index state:
SELECT indexname, use_pq, pq_m
FROM vexdb_index_info()
WHERE indexname = 'idx_pq';CREATE INDEX idx_rabitq
ON items
USING vexdb_graph (vec floatvector_l2_ops)
WITH (quantizer = 'rabitq', m = 16, ef_construction = 100);PG trains RaBitQ only when at least 10,000 samples fit in maintenance_work_mem. In the default full mode, an unavailable quantizer emits a NOTICE and falls back to a plain graph. With memory_mode='compact', activation is mandatory and the build fails instead of writing raw vectors:
CREATE INDEX idx_rabitq_compact
ON items
USING vexdb_graph (vec floatvector_l2_ops)
WITH (quantizer = 'rabitq', memory_mode = 'compact');PG quantized indexes already store only PQ/RaBitQ codes in the index vector fork; they do not keep a second raw-vector mirror. compact therefore acts as a strict storage contract rather than a second compression pass. Omitting quantizer in compact mode selects PQ; quantizer='none' is rejected. Compact indexes are not supported on unlogged tables. ALTER INDEX ... SET (memory_mode='compact') does not rewrite an existing raw index; use REINDEX and verify the effective state through vexdb_index_info().memory_mode plus index_inspect() attributes Working Quantizer and Vector Storage.
SET vexdb.ef_search = 100;
SET enable_seqscan = off;
SELECT id, vec <-> '[0.15, 0.25, 0.35]' AS dist
FROM items
ORDER BY vec <-> '[0.15, 0.25, 0.35]'
LIMIT 10;SELECT id
FROM items
ORDER BY vec <~> '[0.15, 0.25, 0.35]'
LIMIT 10;
SELECT id
FROM items
ORDER BY vec <=> '[0.15, 0.25, 0.35]'
LIMIT 10;LOAD '/path/to/vexdb_lite.duckdb_extension';
SELECT vexdb_version();Typical Python usage:
import duckdb
con = duckdb.connect(config={"allow_unsigned_extensions": "true"})
con.execute("LOAD '/path/to/vexdb_lite.duckdb_extension'")CREATE TABLE items (
id INTEGER,
category VARCHAR,
vec FLOAT[128]
);
CREATE INDEX idx_items_vec
ON items
USING GRAPH_INDEX (vec)
WITH (
metric = 'l2',
m = 16,
ef_construction = 64
);SET vexdb_ef_search = 100;
SELECT id
FROM items
ORDER BY l2_distance(vec, [0.15, 0.25, 0.35]::FLOAT[3])
LIMIT 10;CREATE INDEX idx_items_vec_meta
ON items
USING GRAPH_INDEX (vec, category);
SELECT id
FROM items
WHERE category = 'book'
ORDER BY l2_distance(vec, [0.15, 0.25, 0.35]::FLOAT[3])
LIMIT 10;SELECT inner_product([1.0, 0.0]::FLOAT[2], [0.5, 0.5]::FLOAT[2]);
SELECT cosine_distance([1.0, 0.0]::FLOAT[2], [0.5, 0.5]::FLOAT[2]);
SELECT vector_dims([1.0, 2.0, 3.0]::FLOAT[3]);
SELECT l2_normalize([3.0, 4.0]::FLOAT[2]);
SELECT * FROM vexdb_index_info();Prebuilt packages are recommended. Download the archive for your database, platform, and architecture from the v0.0.17 release, then verify it with the published checksum manifest:
shasum -a 256 -c SHA256SUMS.txtSQLite package names include linux-x86_64, linux-aarch64, macos-arm64, macos-x86_64, ios-xcframework, android-arm64-v8a, android-x86_64, and wasm. Windows prebuilt packages are not available in v0.0.17.
- PostgreSQL 16 ~ 19 (PG 16/17/18/19 supported; primary validation target is
19devel) - CMake ≥ 3.14
- C++17 compiler (GCC 9+ or Clang 10+)
cd /path/to/postgresql-19-source
./configure \
--prefix=/opt/postgresql-19rel-install \
--without-icu \
--without-readline \
--without-zlib \
CFLAGS="-O3 -DNDEBUG"
make -j$(nproc)
make installcd /path/to/VexDB
mkdir -p build-pg19rel-release
cd build-pg19rel-release
export PG_CONFIG=/opt/postgresql-19rel-install/bin/pg_config
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
make installAt minimum:
shared_preload_libraries = 'vexdb_lite'Then restart PostgreSQL and run:
CREATE EXTENSION vexdb_lite;Recommended: use build_duck.sh — it handles DuckDB clone, cmake configuration, compilation, and metadata processing in one command.
bash build_duck.sh setup # First time: clone DuckDB v1.5.2 and cmake configure
bash build_duck.sh build # Compile the extension (incremental)Output: build/duck/build/extension/vexdb_lite/vexdb_lite.duckdb_extension
- CMake ≥ 3.28 and < 4.x
- C++17 compiler (GCC 9+ or Clang 10+)
- Git
DuckDB extensions must be compiled inside DuckDB's source tree — you cannot run cmake -B build vexdb_duckdb/ standalone. build_duck.sh automates:
- Cloning DuckDB v1.5.2
- Writing
extension_config_local.cmaketo register the vexdb_lite extension - Running
cmake+cmake --build - Appending the extension metadata footer (required by DuckDB's release format)
bash build_duck.sh build # Build the extension
bash tests/spec/_lib/docker/run_duckdb.sh test # Run full spec tests (requires Docker)bash tests/spec/_lib/docker/run_pg.sh test # Run PG spec tests (requires Docker + PG19)bash build_sqlite.sh test
bash tests/spec/_lib/docker/run_sqlite.sh testTests are driven by a YAML spec DSL; test files live under tests/spec/.
The v0.0.17 release passed 127/127 DuckDB tests on Linux x86_64 and AArch64, 88/88 PostgreSQL 19 specs on AArch64, and 32/32 SQLite specs against SQLite 3.46.0 and 3.53.4. The iOS Simulator suite also passed M0, M1, SIMD, M2, M3, and M3+ scenarios, including the 40,000-vector parallel-build test with recall@10 of 1.0000.
Dataset: SIFT-1M 128-dim, m=16, ef_construction=128. Columns: QPS (reads=1) / QPS (reads=16) / Recall@10.
Test environment: Intel Core Ultra 7-265K (20c/20t, 3.9 GHz) / 16 GB DDR5 / x86_64 Linux
ef_search = 50
| System | QPS (r=1) | QPS (r=16) | Recall@10 |
|---|---|---|---|
| pgvector | 507.9 | 7153.5 | 96.22% |
| vexdb_lite (PostgreSQL) | 994.7 | 12084.6 | 95.97% |
| vexdb_lite (DuckDB) | 717.5 | 8667.8 | 95.06% |
| duckdb-vss | 496.1 | 5360.9 | 94.07% |
ef_search = 100
| System | QPS (r=1) | QPS (r=16) | Recall@10 |
|---|---|---|---|
| pgvector | 313.4 | 4272.5 | 98.82% |
| vexdb_lite (PostgreSQL) | 618.5 | 7883.1 | 98.62% |
| vexdb_lite (DuckDB) | 547.2 | 5379.1 | 98.40% |
| duckdb-vss | 405.2 | 4433.3 | 98.04% |
ef_search = 200
| System | QPS (r=1) | QPS (r=16) | Recall@10 |
|---|---|---|---|
| pgvector | 193.1 | 2694.1 | 99.66% |
| vexdb_lite (PostgreSQL) | 421.3 | 5038.0 | 99.58% |
| vexdb_lite (DuckDB) | 383.6 | 4298.8 | 99.53% |
| duckdb-vss | 321.9 | 3809.3 | 99.42% |
- Supports PostgreSQL 16 ~ 19; primary validation target is PostgreSQL 19
threadsandpq_moptions are compatibility placeholders on some code paths- ARM Duck builds currently use scalar (
GENERAL) distance dispatch without SIMD acceleration
- iOS, Android, and WASM use static registration; runtime
.loadis for desktop and server builds - v0.0.17 does not include Windows prebuilt packages
| Directory | Description |
|---|---|
common/ |
Shared core: graph index algorithm, SIMD distance dispatch, quantizer (PQ/RaBitQ), template containers |
vexdb_pg/ |
PostgreSQL extension: index AM, build, search, DML, WAL, distance entry |
vexdb_duckdb/ |
DuckDB extension: index lifecycle, optimizer rewrite, distance functions → README |
vexdb_sqlite/ |
SQLite extension: virtual table, shadow-table persistence, PQ/RaBitQ → README |
documentation/ |
Feature docs, build guide |
tests/spec/ |
YAML-based spec tests (shared / pg / duckdb / sqlite) |
scripts/ |
Build, release, and packaging scripts |
thirdparties/ |
Vendored dependencies (patched Boost) |
| Channel | Description |
|---|---|
| GitHub Issues | Bug reports and feature requests |
| GitHub Discussions | Questions, proposals and general discussion |
| Discord | Real-time chat and Q&A |
| WeChat Group | Scan QR code at vexdb.com/community · Chinese community |
MIT License. See LICENSE.