velesdb (Python)

August 17, 2026 · View on GitHub

Embedded vector + graph database for Python: local-first semantic search and explainable agent memory.

PyPI Python License

Licensed under the VelesDB Core License 1.0 (source-available). The compiled wheel embeds the VelesDB engine and is governed by the same license.

Objective

Vector search usually means running a server: a container, a port, a network hop on every query, and an ops story you did not ask for. VelesDB's Python SDK removes all of it — the engine is compiled into the wheel and runs inside your process, against a directory on disk. You get microsecond-scale similarity search, hybrid dense + sparse retrieval, graphs and VelesQL without a daemon, and — when you are building an agent — a memory layer that can explain why it returned what it returned.

If you already run a managed vector service and are happy with it, you do not have this problem and can stop here.

Use cases

  • A RAG prototype on a laptop that must survive pip install and nothing else — no Docker, no cloud account.
  • An AI agent that has to remember decisions across process restarts and justify them later (why()).
  • A desktop or CLI application shipping semantic search inside the app, with the index living next to the user's data.
  • A batch job that embeds a corpus once, writes a portable index directory, and searches it in-process.
  • An offline or air-gapped environment where sending embeddings to a hosted API is not an option.

Prerequisites

RequirementMinimum versionNote
Python3.9requires-python = ">=3.9"; a single cp39-abi3 wheel covers 3.9+
pipany recentprebuilt wheels, no compilation
NumPy1.20hard runtime dependency, installed automatically
Rust1.90only when building from the sdist / source checkout
Embedding modelnot included: VelesDB stores and searches vectors, it does not generate them

Installation

pip install velesdb

Optional extras (all independent, install only what you use):

pip install "velesdb[embed-sentence-transformers]"  # local embedding adapter
pip install "velesdb[embed-openai]"                 # OpenAI-compatible adapter
pip install "velesdb[pandas]"                       # DataFrame ingestion
pip install "velesdb[polars]"                       # Polars ingestion

Building from a source checkout of this repository instead:

pip install maturin
cd crates/velesdb-python
maturin develop

First success in 60 seconds

# pip install velesdb
import velesdb

db = velesdb.Database("./hello_velesdb_data")                 # created if missing
docs = db.get_or_create_collection("docs", metric="cosine")   # dimension auto-detected

# 4-D vectors whose axes stand for four made-up topics: [tech, food, music, sport]
docs.upsert([
    {"id": 1, "vector": [1.0, 0.0, 0.0, 0.0], "payload": {"title": "Rust release notes"}},
    {"id": 2, "vector": [0.0, 1.0, 0.0, 0.0], "payload": {"title": "Best ramen in Tokyo"}},
    {"id": 3, "vector": [0.6, 0.0, 0.8, 0.0], "payload": {"title": "AI-generated jazz"}},
])

results = docs.search_request(velesdb.SearchOptions(vector=[1.0, 0.0, 0.0, 0.0], k=2))
for r in results:
    print(f"score={r['score']:.3f}  {r['payload']['title']}")

Expected output — the exact-match document scores 1.000, the partly-tech one 0.600:

score=1.000  Rust release notes
score=0.600  AI-generated jazz

Anything else is a failure: an empty output means the upsert did not land (check that ./hello_velesdb_data is writable), and a ModuleNotFoundError means the wheel is not installed in the interpreter you are running. The longer version of this script is examples/python/hello_velesdb.py.

Next step, the agent-memory wedge — the same package, no extra install:

from velesdb import MemoryService              # offline, deterministic, no API key

mem = MemoryService("./agent_memory")          # on-disk store; survives restarts
reason = mem.remember("Robert is recovering from knee surgery")
mem.remember("Booked the aisle seat on Robert's flight", links=[(reason, "because")])

mem.why("why the aisle seat on Robert's flight?")   # walks booking → reason

why() returns the best-matching memory plus the connected subgraph reached through typed links — context that shares no words with the question, which a plain vector recall cannot find. See PYTHON_AGENT_MEMORY.md.

Configuration

Database(path, config=...) accepts a typed VelesConfigOptions covering every engine section of the core VelesConfig. Build it in code or load it from a velesdb.toml (engine-only semantics: a shell-owned [server] / [logging] table in a shared file is ignored).

SectionTypeControls
limitsLimitsOptionscollection and resource ceilings
searchSearchConfigOptionsdefault search mode, max results
hnswHnswConfigOptionsindex build/search parameters
storageStorageOptionson-disk storage behaviour
quantizationQuantizationOptionscompression settings
from velesdb import Database, VelesConfigOptions, LimitsOptions, SearchConfigOptions

cfg = VelesConfigOptions(
    limits=LimitsOptions(max_collections=50),
    search=SearchConfigOptions(default_mode="accurate", max_results=100),
)
db = Database("./tenant1", config=cfg)

# Or from TOML (fail-fast: invalid TOML/values raise ValueError,
# a missing file raises FileNotFoundError):
cfg = VelesConfigOptions.from_toml_path("./velesdb.toml")
db = Database("./tenant1", config=cfg)

wal_batch is intentionally not exposed — the concurrent WAL writer is a VelesDB Enterprise feature (see WRITE_CONCURRENCY.md).

Examples

Runnable scripts, not snippets: examples/python/ (hello_velesdb.py, hybrid_queries.py, fusion_strategies.py, graph_traversal.py, graphrag_langchain.py, graphrag_llamaindex.py, multimodel_notebook.py) and the agent-memory demos in examples/agent_memory/.

API / commands

Signatures and docstrings ship inside the wheel as a typed stub (python/velesdb/__init__.pyi, with py.typed), so your IDE and mypy/pyright are the reference. Task-oriented guides:

GuideWhat it covers
PYTHON_API_REFERENCE.mdDatabase / Collection, sparse + hybrid search, fusion strategies, distance metrics, storage modes, bulk loading, streaming ingestion
PYTHON_AGENT_MEMORY.mdMemoryService (remember / recall / why / feedback) and the semantic / episodic / procedural SDK
PYTHON_CONTEXT_COMPILER.mdcompile_context, provenance handles, working contexts, LangChain and LlamaIndex wiring
PYTHON_GRAPH.mdpersistent graph collections, MATCH queries, in-memory GraphStore
PYTHON_VELESQL.mdVelesQL.parse() / ParsedStatement introspection
PYTHON_RAG_PIPELINE.mdtext → embeddings → results, built-in embedding adapters
PYTHON_PERFORMANCE.mdthroughput tuning (numpy f32, upsert_bulk_numpy, batching)
PYTHON_ENGINE_BENCHMARKS.mdmeasured engine latency and recall figures
PYTHON_REMOTE_SERVER.mdtalking to a running velesdb-server over HTTP

Known limits

  • No embedding generation. VelesDB stores and searches vectors; you bring the model (or use the optional adapters).
  • Embedded only. There is no Python client class for a remote server — use HTTP against velesdb-server.
  • One process per database directory. A second process opening the same path fails with DatabaseLockedError ([VELES-031]).
  • wal_batch / concurrent WAL writing is not exposed — Enterprise feature.
  • No GPU in the published wheels. The gpu Cargo feature exists but is not enabled by [tool.maturin]; it requires building from source.
  • Collection.search(...) is deprecated since v1.15 (emits DeprecationWarning); use search_request(SearchOptions(...)).
  • Collection.get_graph_store() returns a standalone in-memory graph that is not connected to the collection; use Database.create_graph_collection() for persistence.

Compatibility

Prebuilt wheels published to PyPI (single cp39-abi3 wheel per platform, so one wheel covers Python 3.9 and later):

PlatformStatusNote
Linux x86_64 (glibc)Prebuilt wheelmanylinux2014 — glibc 2.17+
Linux aarch64 (glibc)Prebuilt wheelmanylinux2014
Linux x86_64 (musl)Prebuilt wheelmusllinux_1_2 — Alpine images
Linux aarch64 (musl)Prebuilt wheelmusllinux_1_2
macOS arm64 + x86_64Prebuilt wheelsingle universal2 wheel
Windows x64Prebuilt wheelMSVC
Windows arm64Prebuilt wheelaarch64-pc-windows-msvc
Anything else (PyPy, exotic arches, older glibc)Source buildsdist fallback, needs Rust 1.90

Troubleshooting

SymptomCauseFix
ModuleNotFoundError: No module named 'velesdb'the compiled extension is not installed in the active interpreter (a source checkout is not importable as-is)pip install velesdb, or maturin develop inside crates/velesdb-python
DimensionMismatchError: ... expected 768 ... 512the vector length differs from the collection's dimensionre-embed with the model that matches the collection, or create the collection with dimension=None to auto-detect on first upsert
DatabaseLockedError: [VELES-031] Database is already opened by another processanother process (or a still-open handle, e.g. a notebook kernel) holds that directoryclose the other handle, or give the second process its own directory
RuntimeError on collection.stream_insert([...])streaming ingestion was never enabledcall collection.enable_streaming(...) first
FileNotFoundError from VelesConfigOptions.from_toml_path(...)config loading is fail-fast by designcheck the path; malformed TOML or invalid values raise ValueError instead

All typed exceptions (DimensionMismatchError, CollectionNotFoundError, CollectionExistsError, EdgeExistsError, DatabaseLockedError, VelesQLSyntaxError, VelesQLParameterError) derive from velesdb.VelesDBError, so except velesdb.VelesDBError is a safe catch-all.


velesdb-python v5.1.0 · Last updated: 2026-08-10 · Applies to: velesdb-core 5.1.0 · Report a docs error