zvec: run vector search inside your app, no server, offline
Embed a vector database directly into your process with zvec, insert vectors, and query for nearest neighbors, with no separate server to run, config, or babysit.
Run this workflow
CI-verified, 2/2 fixtures passing.
Build this with your agent
One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.
Intended Use
Anyone adding retrieval or memory to an app without wanting to run a vector server. CI installs zvec from PyPI, creates a collection, inserts two vectors, and queries, asserting it returns both results with the correct nearest neighbor, offline and with no key. What you embed and retrieve on real data is fenced.
Not for
- Many-writer or horizontally scaled services, in-process means one writer at a time and no clustering; use Milvus or Qdrant there
- Intel Macs, the current build is macOS ARM64 only (Linux x86_64/ARM64 and Windows x86_64 are supported)
- Quoting the 'billions of vectors in milliseconds' headline, that is Alibaba's own benchmark; measure it on your data and hardware
The Stack
Tested Against
zvec (PyPI, 2026-07)python@3.10-3.14Side effects & data flow
- Network
- PyPI, install only; search is fully in-process
- Writes
- ./.venv/, a temp collection dir
- Credentials
- none required
Prerequisites
- Python 3.10+
- pip
Steps
- 1
Install zvec and run an in-process insert + query
pip install zvec, then create a collection on a fresh path, insert two vectors, and query for the nearest neighbor. There is no server: the database lives in your process. CI runs exactly this and checks the query returns the expected nearest neighbor.
python3 -m venv .venv .venv/bin/pip install -q zvec .venv/bin/python - <<'EOF' import zvec, tempfile, os schema = zvec.CollectionSchema( name="example", vectors=zvec.VectorSchema("embedding", zvec.DataType.VECTOR_FP32, 4), ) path = os.path.join(tempfile.mkdtemp(), "zvec_example") collection = zvec.create_and_open(path=path, schema=schema) collection.insert([ zvec.Doc(id="doc_1", vectors={"embedding": [0.1, 0.2, 0.3, 0.4]}), zvec.Doc(id="doc_2", vectors={"embedding": [0.2, 0.3, 0.4, 0.1]}), ]) results = collection.query( zvec.VectorQuery("embedding", vector=[0.4, 0.3, 0.3, 0.1]), topk=10, ) ids = [r.id for r in results] assert len(ids) == 2, "expected 2 results, got " + str(len(ids)) assert ids[0] == "doc_2", "nearest neighbor should be doc_2, got " + str(ids[0]) print("zvec OK: in-process vector search returned 2 result(s) offline, no server; nearest neighbor is doc_2") EOF - 2
Point it at your own embeddings (the retrieval step, not checked by CI)
Swap the toy vectors for real embeddings from your model, use hybrid queries (vector plus structured filters) if you need them, and persist the collection dir so it survives restarts. What you retrieve on real data is fenced.
Eval, 2 fixtures
Last passed: verified todaysearch-okcontainstimeout 900s · max $0Expected:
zvec OK: in-process vector search returned 2 result(s) offline, no server; nearest neighbor is doc_2clean-exitexit_codetimeout 900s · max $0Expected:
0
Results
zvec is the SQLite of vector search: Alibaba Tongyi Lab's in-process vector DB, battle-tested internally (it wraps the Proxima engine behind Taobao and Alipay). It does dense and sparse vectors, hybrid search, and write-ahead logging for crash safety. In-process is the strength and the limit: one writer at a time, no clustering, so it is right for an app, notebook, CLI, or edge device, and wrong when you need a many-writer server like Milvus or Qdrant.
Did this work for you?
Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.
Related workflows
- LlamaIndex: index your documents and query them at runtime
- Crawl4AI: a page to clean, LLM-ready markdown (no API key)
- Khoj + Fable 5: A Second Brain That Knows Your Notes
- Cognee: Knowledge-Graph Memory Over Your Documents
- Obsidian × MCPVault: Write a Note from Any MCP Client
- Obsidian × MCPVault: Read a Note from Any MCP Client
Liked this workflow?
Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).