Skip to main content

GraphVec

GraphVec is a local, file-based vector search library for Python. It stores an index in a directory on disk and finds nearest neighbours with its own HNSW-style graph. It needs no database server, cloud service, or background process.

It is written in pure Python (3.11+) and NumPy. That makes it easy to read and embed, but it is slower than compiled libraries such as FAISS or hnswlib.

Installation

pip install graphvec-ann           # the import name and command are `graphvec`
pip install "graphvec-ann[parquet]"  # optional Parquet import

Quick start

import numpy as np
from graphvec import GraphIndex

rng = np.random.default_rng(42)
vectors = rng.random((1_000, 128), dtype=np.float32)
ids = [f"doc-{i}" for i in range(len(vectors))]

with GraphIndex.create("./vectors.gvec", dimensions=128, metric="cosine") as index:
    index.add(vectors, ids=ids)
    index.save()  # nothing is written to disk until save()

with GraphIndex.open("./vectors.gvec", readonly=True) as index:
    query = rng.random(128, dtype=np.float32)
    for result in index.search(query, k=5, ef_search=100):
        print(result.id, result.score)

Python API

Method Purpose
GraphIndex.create(path, dimensions, metric="cosine", max_neighbors=16, construction_ef=200, seed=42, overwrite=False, memory_limit=None) Create a new index directory
GraphIndex.open(path, readonly=False, verify_checksums=False, memory_limit=None) Open an index (read-only mode memory-maps vectors)
add(vectors, ids=None, replace=False, insert_batch=1) Insert vectors; duplicate IDs raise DuplicateIDError unless replace=True
search(query, k=10, ef_search=100) / search_batch(queries, ...) Approximate search; returns SearchResult(id, score, internal_id)
search_exact(query, k=10) Brute-force search, useful to measure recall
get(id) / contains(id) / delete(ids) / iter_ids() Read, check, delete, or list IDs (deletes are tombstones)
compact() / build() Drop deleted rows, rebuild the graph and save / only rebuild the graph
save() / close() / validate() Commit to disk, release the writer lock, check consistency
GraphIndex.force_unlock(path) Remove a stale writer lock after a crash

Higher ef_search gives better recall but slower queries. All errors inherit from graphvec.GraphVecError.

Metrics (metric=):

  • cosine: score is cosine similarity, higher is better. Vectors are normalised when added, so get() returns the normalised vector. Zero vectors score 0.
  • dot: score is the dot product, higher is better.
  • squared_euclidean: score is the squared L2 distance, lower is better.

Command line

graphvec create ./index.gvec --dimensions 128 --metric cosine
graphvec import ./index.gvec vectors.npy --ids ids.json   # or .jsonl / .parquet
graphvec search ./index.gvec --query-file query.npy --top-k 10
graphvec info ./index.gvec
graphvec validate ./index.gvec
graphvec benchmark ./index.gvec --queries queries.npy --top-k 10
graphvec compact ./index.gvec
graphvec unlock ./index.gvec                              # after a crashed writer
graphvec export ./index.gvec --output vectors.npy         # also writes vectors.npy.ids.json

JSONL records look like {"id": "doc-1", "vector": [0.1, ...]}; Parquet files need id and vector columns and the parquet extra. Most commands accept --json; see graphvec --help.

Limitations

  • Read-only opens memory-map vectors and the graph. Writable indexes keep them in RAM up to memory_limit (default: a quarter of physical memory), then in memory-mapped working files, so building can exceed RAM; the ID map always stays in RAM.
  • One writer at a time. A crash leaves a stale lock; clear it with graphvec unlock.
  • Deleted IDs cannot be reused until compact().
  • Insertion is slow (hundreds of vectors per second in our measurements).
  • More detail and crash-safety guarantees: docs/limitations.md.

Documentation

Architecture and algorithms · File format · Benchmarks · Changelog · Security

Development

Add tests for behaviour changes, and never commit benchmark numbers you did not measure.

pip install -e ".[dev]"
pytest                                   # add -m slow for large tests
ruff check . && ruff format --check .
mypy src/graphvec

License

MIT. See LICENSE.

Metadata

Release files for graphvec-ann 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for graphvec-ann 0.3.0
File Size Uploaded Provenance
graphvec_ann-0.3.0.tar.gz 63.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for graphvec-ann 0.3.0
File Interpreter ABI Platform
graphvec_ann-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 99.7 kB

Release files / graphvec_ann-0.3.0.tar.gz

Download URL graphvec_ann-0.3.0.tar.gz
Size 63.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a09bf45cc6d2546279e2fda0bf84c286384f9f5fa00e6ff2fce7b2cade6a9eef
BLAKE2b-256 checksum
How to use checksums
abd1659724fed85d4dab483178e26f146bade67320ee0fbe32f32644d10eaa99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / graphvec_ann-0.3.0-py3-none-any.whl

Download URL graphvec_ann-0.3.0-py3-none-any.whl
Size 35.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4c1228dcc118865ad6897137e0c35678d9bd80e3ebd04cc186b034ac23854cfe
BLAKE2b-256 checksum
How to use checksums
7ff2d49a8f7ec8309c84eaf47fc15938b5981bf46d94737d3884402ae3420448
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Security for graphvec-ann 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for graphvec_ann-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page