Files
yvgude--lean-ctx/docs/guides/dense-backends.md
T
wehub-resource-sync 26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

5.0 KiB

Dense Backends — where your vectors live

The dense (embedding) half of lean-ctx's hybrid retriever needs a vector store. By default that store is in-process and on disk — no service, no container, nothing to operate. For teams that already run a vector database, lean-ctx can delegate dense search to it instead.

Backend Runs where Setup Best for
local (default) inside the lean-ctx process, persisted next to the BM25 index none individuals and most teams — zero-ops, deterministic
qdrant your Qdrant server (self-hosted or cloud) LEANCTX_QDRANT_URL fleets sharing one index, corpora beyond one machine's RAM
pgvector your PostgreSQL with the pgvector extension LEANCTX_PGVECTOR_URL + psql client orgs that already operate Postgres and want vectors under existing backup/HA/access policies

Both backends consume the same embedding pipeline — the local ONNX model selected via [embedding].model produces the vectors; only the storage and the nearest-neighbor search move. BM25, SPLADE, RRF fusion and reranking are unaffected by the backend choice.

Selecting a backend

# Explicit
export LEANCTX_DENSE_BACKEND=local    # default
export LEANCTX_DENSE_BACKEND=qdrant
export LEANCTX_DENSE_BACKEND=pgvector

# Implicit: setting a backend URL selects that backend automatically
export LEANCTX_QDRANT_URL=http://127.0.0.1:6333
export LEANCTX_PGVECTOR_URL=postgres://user:pass@127.0.0.1:5432/leanctx
# (if both URLs are set, qdrant wins — set LEANCTX_DENSE_BACKEND to override)

An unknown value fails fast with a clear error rather than silently falling back — retrieval quality should never degrade without you noticing.

Qdrant configuration

export LEANCTX_QDRANT_URL=http://127.0.0.1:6333   # required
export LEANCTX_QDRANT_API_KEY=# optional (Qdrant Cloud / secured instances)
export LEANCTX_QDRANT_TIMEOUT_SECS=10             # optional, default 10
export LEANCTX_QDRANT_COLLECTION_PREFIX=lctx_code_ # optional, default shown
  • Collections are per project and per model dimension — the collection name is derived from the project root's namespace hash and the embedding model's vector width, so switching models can never mix incompatible vectors.
  • Sync is incremental. On each dense search lean-ctx upserts only chunks of files that changed since the last sync (delete-by-file, then re-upsert). A fresh collection is populated once.
  • The build stays quiet. The qdrant and pgvector build features are part of the default feature set (so release binaries have them); requesting a backend whose feature was compiled out produces an explicit error, not a silent local fallback.

Run a local Qdrant for testing:

docker run -p 6333:6333 qdrant/qdrant
LEANCTX_QDRANT_URL=http://127.0.0.1:6333 lean-ctx search --semantic "auth flow"

pgvector configuration

export LEANCTX_PGVECTOR_URL=postgres://user:pass@127.0.0.1:5432/leanctx  # required
export LEANCTX_PGVECTOR_TIMEOUT_SECS=10                                  # optional, default 10
export LEANCTX_PGVECTOR_TABLE_PREFIX=lctx_code_                          # optional, default shown
  • Talks through the psql CLI — no native driver, no async runtime added to lean-ctx. The PostgreSQL client tools must be on PATH (macOS: brew install libpq, Debian/Ubuntu: apt install postgresql-client).
  • Tables are per project and per model dimension (same namespacing rule as qdrant collections): lctx_code_<namespace-hash>_d<dims>, created on first use together with CREATE EXTENSION IF NOT EXISTS vector. The database user needs extension-create rights once (or a DBA pre-installs the extension).
  • Same incremental sync — delete-by-file then re-upsert for changed files, one full upsert for a fresh table. Point ids are identical to the qdrant scheme, so backend switches never mix identities.
  • Search is exact (ORDER BY embedding <=> query) — correct at any corpus size, and you can add an HNSW/IVFFlat index in Postgres later without any lean-ctx change.

Run a local pgvector Postgres for testing:

docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=lctx pgvector/pgvector:pg16
LEANCTX_PGVECTOR_URL=postgres://postgres:lctx@127.0.0.1:5432/postgres \
  lean-ctx search --semantic "auth flow"

What stays true regardless of backend

  • Embeddings are produced locally (ONNX; swappable via hf:org/repo) — no embedding API, no per-token fees.
  • The lexical BM25 floor is always available: if the dense backend is unreachable, hybrid search degrades to BM25 with a warning instead of failing the query.
  • Chunk identity is content-derived, so re-indexing an unchanged corpus is a no-op on the store.

See also: Context Infrastructure, Custom Embedding Models, lean-ctx vs naive RAG.