vlite: a vector database in one numpy file with a cookie-like storage format
fastest vector database made in numpy
At a glance
- What is it?
- vlite stores embeddings in a CTX file you can copy between machines, retrieves with binary embeddings in under a second across half a million documents, and depends on nothing but numpy. It is aimed squarely at retrieval augmented generation, and the interesting trade is that the whole library is a single Python module whose licence is AGPL-3.0, which is a serious constraint for anyone who planned to put it inside a product.
- Who is it for?
- Adopt vlite if you are prototyping a retrieval augmented generation feature and want a working vector store in a single file with no server to run, since the CTX format and the numpy-only dependency make the whole thing portable in a way most vector databases are not.
- Can I use it commercially?
- Yes. MIT 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 last received commits 31 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One file, one dependency, no server
vlite is described as a simple and blazing fast vector database, and the pitch is stated in the plainest possible terms: there is no database you need to set up, no server to run, and no complex configuration. You install vlite and start using it, and you take the CTX file with you wherever you go. It is like a browser cookie but with embeddings.
That framing is the design. There is no server process, no daemon, no port, no connection string, and no index server to keep alive. The whole library is one module. The setup.py declares py_modules with the comment that the whole library is vlite.py, and the repository top level confirms it, with vlite.py, an ARCHITECTURAL.md, a setup.py and the README.
The runtime dependency list is a single entry, numpy with a version of 2 or above, and the comment explains why the floor matters: np.bitwise_count is needed, and the tokenizer and model are plain numpy inside vlite.py. The Python floor is 3.10.
The model is baked in rather than pluggable. The README says it is made for RAG, with embeddings from the mixedbread embed-xsmall model, run in plain numpy, and numpy is the only dependency. The first run downloads a 48 MB model to a cache directory, and the README says that plainly.
So the shape of the thing is: a single file, a single dependency, one hard-wired embedding model, and a storage format you can email to someone. Whether that is right for you depends entirely on what you are building.
The API in one screen, and the shape of a result row
The usage section is short enough to read twice, and the example is the Borges library, which is a better test of a retrieval system than a set of near-duplicate sentences.
from vlite import VLite
db = VLite("borges")
db.add(["a library of hexagonal rooms that holds every possible book",
"a man who remembers every leaf of every tree he has ever seen",
"a garden where time forks into every possible future"])
for _, text, _, distance in db.retrieve("parallel timelines", top_k=2):
print(distance, text)
db.save()The output for that query is a garden where time forks into every possible future, at distance 148, and a man who remembers every leaf of every tree he has ever seen, at distance 167. Lower distance means closer.
Each result is a tuple of id, text, metadata and distance. The id and metadata are unpacked and discarded in the example because the query did not need them, but they are there, which is what makes the metadata filtering possible.
The save call writes everything to a contexts/ directory with the name of the database and a .ctx extension, and VLite("borges") picks it back up the next time. That round trip is the whole product: create, populate, save, ship the file, load it somewhere else.
The API is deliberately small. There is a constructor, an add, a retrieve with a top_k, a save, and metadata filtering. There is no server, no collection concept, no schema.
Metadata filtering, and why it is a differentiator rather than a checkbox
Metadata filtering is built in, and the example shows how it changes the answer rather than merely narrowing a list.
db.add(["a point in a cellar that contains every other point in the universe",
"a coin that, once seen, can never be put out of mind"],
metadata={"book": "the aleph"})
db.retrieve("perfect memory", top_k=1) # the man who remembers everything
db.retrieve("perfect memory", top_k=1, where={"book": "the aleph"}) # the coin you can't forgetThe first query, unfiltered, returns the man who remembers every leaf of every tree, which is the semantically closest thing in the collection. The second query adds a where clause and gets a different result back, the coin from the Aleph, because the filter restricts the candidate set before ranking rather than after.
That ordering is the part that makes filtering worth having. If you filter after ranking you get the top_k results and then discard the ones that do not match, which means a narrow filter can return fewer results than you asked for. Filtering first means the filter is part of the search, so top_k=1 still gives you one result, and it is the best matching one within the filter.
Metadata is attached per item at add time as a dictionary. The format of the metadata is not restricted by the library as far as the documentation shows, so the practical constraint is that it has to be something the library can store in the CTX file and compare against a where clause.
Long text is chunked for you. The README says long texts get chunked automatically, to the model 512-token window, and that vlite only takes strings, so you bring your own PDF reader.
Binary embeddings, and the speed claim you should read carefully
The headline numbers are specific and worth reading with the same care as any benchmark.
The feature list claims fastest vector db retrieval with binary embeddings, less than 1.1 seconds to search 500k documents. The comparison line is that it is more than 77.95 percent faster than Chroma on indexing, more than 422 percent faster on retrieval, and more than 3.6x smaller on disk.
Two things are worth separating. The speed comes from a specific design choice, which is binary embeddings, and the mention of np.bitwise_count in the dependency comment is the giveaway: binary embeddings are bit vectors, and bitwise population count is how you compute Hamming distance between them cheaply. That is a fundamentally different retrieval strategy from floating point cosine similarity over dense vectors.
The trade-off is inherent to the technique, though the README does not spell it out, and you should think about it before you adopt. Binary embeddings throw away information compared with float embeddings, so recall at a given precision will generally be lower. The library is betting that for its target use, which is retrieving chunks of context for a language model, a fast approximate result beats a slow exact one. That bet can be right, particularly when the retrieved content is going to be read by a model that can cope with a slightly wrong chunk, and it can be wrong for a system where the top hit has to be exactly right.
The repository also has a benchmarks/ directory and an ARCHITECTURAL.md, and the release history shows the project has been rebuilt at least once: v0.2.0 was described as vlite2, the fastest retrieval vector database with a new file format for context storage.
The benchmark directory is where you should look if the comparison numbers matter to you, since the claims are the author comparing against a competitor and the methodology is in the repository.
The CTX format, and where the project came from
The CTX file format is the project's original contribution, and the description is deliberately informal: a novel abstraction for storing user context similar to browser cookies, acting like a browser cookie for user embeddings, providing efficient storage, retrieval of embeddings, composability, portability, and user context.
The idea is that a small file of embeddings is a portable unit of state. A browser cookie holds a session; a CTX file holds everything known about a user, and it can be handed to another process, another machine, or another service.
That origin story explains the whole design. vlite was developed to support the billions of embeddings generated, indexed, and sorted with the ChatWith+ ChatGPT plugins, which run for millions of users. The README gives the reason in one sentence: most vector databases either repeatedly crashed on a daily basis or were too expensive for the high throughput required.
So this is a library born from an operational problem at scale, and it explains the priorities. A single file that can be written and read cheaply scales in a way a server-based database does not, because there is no coordination. The cost is that the design is unusual, and the format is versioned, with the setup.py version carrying the note that 0.3.0 is breaking, with a new API and the .ctx v2 format.
That version note is worth pausing on. The released versions in the list are v0.2.2, v0.2.1 and v0.2.0, all from April 2024, and the source in setup.py is at 0.3.0 with a breaking change. So the tag and the source are on different sides of a format break, and the last push to the repository was on 2026-09-22.
The licence is the real decision, and the records disagree
This is the part that needs a decision before you write any code.
The README says AGPL-3.0 License, and the setup.py classifiers list License :: OSI Approved :: GNU Affero General Public License v3. The platform, meanwhile, records the licence for the repository as MIT. Those are not the same licence, and for a library you might embed in a hosted service, the difference between MIT and AGPL is the difference between a permissive dependency and a copyleft one that reaches into how you distribute your service.
So before you depend on vlite, read the LICENSE file at the root of the repository and work out which record is current. It is entirely possible the platform's MIT record is a stale classification, and it is equally possible the reverse. Either way, guessing is the wrong move, because the consequence of getting it wrong is a legal problem rather than a bug.
The development status classifier is 4 - Beta, which is a more modest claim than the speed numbers in the README, and the topic classifier is Software Development, Libraries, Python Modules.
The other thing to consider before adopting is the baked-in model. Embeddings from mixedbread embed-xsmall are downloaded on first run and used to encode your text, so the vectors in your CTX file are tied to that model. If you later want a different model, or want to embed with a GPU-accelerated service and store the result, you have to check whether the file format lets you bring your own vectors. The documentation as given does not make that clear, and it is the first question to answer if you are building something where the embedding model is not your choice.
The project is by Surya Dantuluri, and the credits mention contributions from Claude and from Ray Del Vecchio.
Editorial conclusion
Adopt vlite if you are prototyping a retrieval augmented generation feature and want a working vector store in a single file with no server to run, since the CTX format and the numpy-only dependency make the whole thing portable in a way most vector databases are not. Do not adopt it for a product you intend to distribute, because the licence recorded in setup.py and in the README is AGPL-3.0, and the platform records a different licence for the repository, so you need to resolve that before you ship anything. Before you commit, check that the model it downloads is one you are willing to depend on, since the embeddings are baked in rather than pluggable.
Frequently asked questions
How do I install and use vlite?
Run pip install vlite, then create a VLite instance with a name, add your strings, retrieve with a top_k, and call save() to write the CTX file. The first run downloads a 48 MB model to the cache directory, and numpy is the only dependency.
What licence does vlite use?
The README and the setup.py classifiers both state AGPL-3.0, while the repository is recorded elsewhere as MIT. Read the LICENSE file in the repository to determine the actual terms before you depend on it, especially if you plan to embed it in a distributed or hosted product.
How does vlite handle metadata filtering?
You attach metadata as a dictionary when adding items, and pass a where clause to retrieve, for example db.retrieve("perfect memory", top_k=1, where={"book": "the aleph"}). The filter restricts the candidate set so the top_k results are the best matches within the filter.
Does vlite need a server or a running database?
No. There is no database to set up and no server to run. Everything is written to a single CTX file under a contexts directory, and the file can be copied elsewhere and reopened with the same name.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sdan-vlite)Was this useful?