Model or dataset
alibaba/zvec avatar
alibaba/zvec

alibaba/zvec: an in-process vector database that trades a server for a file path

A lightweight, lightning-fast, in-process vector database

15,934 stars997 forksC++Apache-2.0

At a glance

What is it?
Zvec is an embedded C++ vector database with Python, Node.js, Go, Rust and Dart SDKs, Apache-2.0 licensed, and it puts dense vectors, sparse vectors, full-text search and structured filters behind one local collection object. The judgement: it fits single-writer applications that want ANN search without operating a service, and it is the wrong tool the moment you need concurrent writers or a shared index across machines.
Who is it for?
Adopt zvec if your application is the only writer to its index and you want vector, sparse and full-text search without a separate service to deploy: the Python quickstart is a pip install, a CollectionSchema, and a create_and_open call on a local path. Do not adopt it if two processes must write the same collection at once, since the README states writes are single-process exclusive, or if you need a network endpoint that many clients share.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The server you delete, not the database you add

Most vector search deployments start with a service. You provision a node, expose an endpoint, manage credentials, and then write application code whose only job is to make a network round trip to an index that lives somewhere else. For a laptop tool, a CLI, a notebook, a mobile app or a single-process agent runtime, that entire layer is overhead. Zvec removes it. The README describes the project as an in-process vector database designed to embed directly into applications, and the quickstart bears that out: a collection is created at a filesystem path, not registered with a server. The audience is therefore narrow and specific. It is the engineer building a retrieval component inside a larger program, who wants approximate nearest neighbour search, keyword search and metadata filtering available as function calls in the same process, and who is willing to accept the constraints that come with owning the storage file. If you need a shared index that ten services query over HTTP, this is not the shape of tool you are looking for, and the README does not pretend otherwise.

Collections, schemas and where the vectors actually live

The unit of organisation is the collection. In the Python example, a CollectionSchema takes a name and a VectorSchema that declares a field name, a data type (VECTOR_FP32 in the sample) and a dimension. Documents are inserted as Doc objects carrying an id and a mapping from field name to vector. Queries are constructed as a Query with a field_name and a vector, plus a topk argument, and the result is described in the README comment as a list of dictionaries with id and score keys sorted by relevance. That is the whole surface for the simplest case, and it is deliberately small. What sits underneath is where the design decisions are. The feature list mentions dense and sparse embeddings, multi-vector queries, and a selection of index types that scale from memory to disk, with a link to a concepts page on vector index types. The v0.7.0 release notes name several of them: DiskANN, an IVF-RaBitQ index, and a PQ-INT8 quantizer. DiskANN is the disk-resident path, and v0.7.0 adds an io_uring async I/O backend for it with what the notes describe as automatic fallback to the best available I/O option. RaBitQ is documented as supporting runtime AVX2 and AVX512 dispatch, meaning one binary selects the SIMD path at runtime rather than at compile time. Those are the mechanisms that determine whether your collection fits in RAM and how fast it answers, and they are selectable, which means the index type is a decision you make rather than a default you inherit.

Hybrid search is the actual differentiator, not the ANN index

Standalone ANN libraries are plentiful, and the README's own topics list includes faiss, which tells you the authors know what they are being compared against. The reason to pick zvec over a bare index library is the query layer. The feature list describes hybrid search as fusing vector similarity, full-text search and structured filters in a single query. That matters because real retrieval rarely reduces to cosine distance. You want the top-k nearest neighbours that also match a tenant id, or a keyword that must appear in the text, or both ranked together. Doing that outside the database means fetching a large candidate set and re-ranking it in application code, which is where latency and correctness bugs accumulate. Zvec's full-text search is described as native keyword search over string fields, with natural-language or structured expressions, and v0.7.0 adds an N-gram tokenizer that the release notes say is better suited to phrase, code and short-text search. The N-gram choice is telling: it is the tokenizer you reach for when your text is identifiers and code fragments rather than prose, which lines up with the zvec-grep tooling mentioned in the same release. This is the part of the project that a thin ANN wrapper cannot replicate, and it is the strongest argument for adopting the whole thing rather than a component of it.

Getting a collection open: the commands and the config surface

Installation is per language and the README lists them plainly. Python is pip install zvec, with a stated requirement of 64-bit Python 3.10 through 3.14. Node.js is npm install @zvec/zvec. Rust is cargo add zvec-rust. Dart and Flutter get it through flutter pub add zvec. Go bindings are linked from a separate repository rather than a package manager command. Supported platforms are listed as Linux on x86_64 and ARM64 with both glibc and musl, macOS on ARM64 and x86_64, and Windows on x86_64. The Alpine and musl support is new in v0.7.0, and the release notes also mention prebuilt SDK binaries for Linux, macOS, Windows, Android and iOS published with each release, which is what makes the mobile targets plausible without a cross-compilation exercise. The runtime configuration surface visible in the material is small by design. You choose a path, you choose a schema, you choose an index type. There is no server config file, no port, no cluster settings. That is the pitch: the README says pure local, no servers, no config. The one configuration decision that carries real consequences is the index type, since that is what determines whether the collection lives in memory or on disk. The documentation points to a separate concepts page for the index type list, so the README alone will not tell you which to pick for your data.

WAL durability and the single-writer constraint

Two storage properties are stated explicitly, and they pull in opposite directions for some workloads. First, durability: the README says write-ahead logging guarantees persistence, with the claim that data is not lost even on process crash or power failure. That is a stronger statement than most embedded stores make, and it is the right one for an index that a user spent hours embedding. Second, concurrency: multiple processes can read the same collection simultaneously, but writes are single-process exclusive. Read that constraint carefully, because it eliminates a whole class of architectures. You cannot run two worker processes that both ingest into one collection. You cannot have a background indexer and a foreground writer sharing a file. The workaround is a single writer process that owns the collection and serves reads to others, which is a design you have to build yourself, and at that point you have reintroduced a small server. The honest reading is that zvec's concurrency model matches its intended deployment: one application process, one collection, many reads within that process. If your ingestion is naturally parallel, this is a friction point, and the README does not describe a mechanism for coordinating multiple writers.

Where zvec is the wrong tool, and what to use instead

The clearest case against zvec is a shared index behind a network boundary. If several services, languages or machines need to query the same vectors, an embedded library forces you to either replicate the collection to each consumer or wrap it in your own service. A server-based vector database such as Milvus, Qdrant or Weaviate takes the opposite approach: the index is a long-running process with an HTTP or gRPC API, replication and sharding are the database's problem, and clients are thin. The trade is operational weight against architectural flexibility. Zvec moves the index into your process, which removes the network hop and the deployment, and in exchange you own the file lifecycle, the writer serialisation and the upgrade path. There is a second, less obvious alternative worth naming: a general-purpose embedded store with a vector extension, or a plain ANN library plus SQLite for the metadata. That combination can cover filtered vector search, but it pushes fusion between keyword and vector results into your application code, which is precisely the work zvec's hybrid query is designed to absorb. Choose zvec when the fusion and the local file are the point. Choose a server when sharing is the point.

Upgrades, prebuilt binaries and what Apache-2.0 leaves you to decide

Release cadence is visible from the tags: v0.5.1 in June 2026, v0.6.0 in July, v0.7.0 in August. That is roughly monthly, and v0.7.0 is a large release by the notes' own account, adding index types, a new tokenizer, a new I/O backend and new platform targets. For an embedded library, a fast cadence cuts both ways. You get the index improvements without waiting, but every upgrade is a dependency bump inside your own binary, and the release notes show platform-level changes (musl support, ARM64 DiskANN, io_uring) that alter what your build links against. The prebuilt dynamic library size reduction mentioned for the macOS arm64 C API library, 37 MB down to 22 MB, is a reminder that you are shipping native code, not a script. The licence is Apache-2.0, which is permissive and includes an explicit patent grant, and the practical implication is that embedding it in a closed-source product is permitted. That is a statement about the licence text, not legal advice; if you are redistributing the prebuilt SDK binaries or modifying the C++ core, have your own counsel read the NOTICE and attribution requirements. The maintenance cost that matters most is not the licence. It is that you now own a native dependency with a monthly release train and a single-writer storage file, and neither of those is something the library can absorb for you.

Editorial conclusion

Adopt zvec if your application is the only writer to its index and you want vector, sparse and full-text search without a separate service to deploy: the Python quickstart is a pip install, a CollectionSchema, and a create_and_open call on a local path. Do not adopt it if two processes must write the same collection at once, since the README states writes are single-process exclusive, or if you need a network endpoint that many clients share. Before committing, verify three things against your own data: which index type your collection uses, whether the disk-based path (DiskANN with the io_uring backend on Linux) is what you actually benchmarked, and how the WAL behaves on an unclean shutdown in your deployment target.

Official sources

  1. alibaba/zvec on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes