Creator of sqlite-vec here, happy to help debug anything if you do attempt to try out SQLite vector search again.
You mentioned "VSS" in another comment, which if that was my sqlite-vss extension, I more-or-less abandoned that extension for sqlite-vec last year. The VSS extension was more unstable and bloated (based on Faiss), but the new VEC extension is much more lightweight and easy to use (custom C vector functions). The new metadata column support is also pretty nice, and can be used for push-down filtering.
That being said, sqlite-vec still doesn't have ANN yet (but can brute-force ~10k's-100k of vectors quick enough), and I've fallen behind on updates and new releases. Hoping to push out a desperately-needed update this week
Hey Alex - thanks for commenting. I'd be interested in giving this all another look. Like we mentioned in the post + comments, We went with redis because that's what got us the results we wanted. I'm open to revisiting our vector storage if it spares us needing to manage a separate db process.
I really dig more content about how vector databases/tools handle problems like this!
In sqlite-vec, there's only a flat brute-force index (though DiskANN/IVF will be coming soon). But we do have a concept of partition keys[0], which allows you to "internally shard" the vector index based on a user_id or any other value.
Then at query time, any WHERE constraints on a partition key are pushed-down, so only matching vectors are searched instead of the entire index.
select
document_id,
user_id,
distance
from vec_documents
where contents_embedding match :query
and k = 20
and user_id = 123; -- only search documents from user 123
Definitely not as performant as a proper vector index, but a lot of real-world application have these natural groups anyway. Like "search only English documents" or "search entries in this workspace only", or even "search comments only from the past 30 days."
Internally sqlite-vec stores vectors in "chunks", so when partition keys are definds, every chunk is associated with a unique combination of all partition keys. Kinda hard to describe, but if you create a vec0 virtual table and insert some values, you can inspect the internal "shadow tables" in the SQLite database to see how it's all stored.
Well, I have a brute force strategy for pgvector working reasonably well. Individual, partial indexes. It works for all those queries with category_id=<> clauses. You only need an index for larger categories, for categories with rows below a threshold you dont need index a KNN/dot product would work.
vec0 virtual tables have a hard-coded max of 8192 dimensions, but I can raise that very easily (I wanted to reduce resource exhaustion attacks). But if you're comparing vectors manually, then the `vec_distance_ls()` and related functions have no limits (besides SQLite's 1GB blob limit)
Really curious to hear about what kind of music embedding models/tools you used! I've tried finding some good models before but they were all pretty difficult to use
In the past I mainly screwed around with [2] musig as it was fairly easy to modify, right off hand I don't know why I stopped using it. [1] seek-tune (not-shazam) was just post here on hn yesterday, I had to modify it quite a bit to actually get something working in a way I was happy with. Overall it was a little slow, but that's not something I'm gonna fault the author for as the project is still quite new. While browsing around yesterday after messing with [2], I found [3] cpuimage/shazam. It's a little easier for me to screw around with as it's in c, and would probably be the one I try and modify to use this project.
Everything is based on the shazam algorithm or something similar, so chunking the audio stream, and fingerprinting it. I was focused on that because it allows me to figure out where OP and ED are in some anime and allows me to add a skip button. Also since anime in the same season typically have the same OP/ED I can use that to try and auto categorize them after the first ones been identified.
TL;DR: It's all shazam look alikes, everything else was to annoying to use.
You can generate "text embeddings" (ie vectors) from your text with an embedding model. Once you have your text represented as vectors, then "closest vector" means "more semantically similar", as defined by the embedding model you use. This can allow you to build semantic search engines, recommendations, and classifiers on top of your text and embeddings. It's kindof like a fancier and fuzzier keyword search.
I wouldn't completely replace keyword search with vector search, but it's a great addition that essentially lets you perform calculations on text
Nice explanation. One use case where keywords haven't worked well for me , and (at least at first glance) vectors are doing better are longer passages -- finding sentences that are similar rather than just words.
Author here, happy to answer any questions! Been working on this for a while, so I'm very happy to get this v0.1.0 "stable" release out.
sqlite-vec works on MacOS, Linux, Windows, Raspberry Pis, in the browser with WASM, and (theoretically) on mobile devices. I focused a lot on making it as portable as possible. It's also pretty fast - benchmarks are hard to do accurately, but I'd comfortable saying that it's a very very fast brute-force vector search solution.
One experimental feature I'm working on: You can directly query vectors that are in-memory as a contiguous block of memory (ie NumPy), without any copying or cloning. You can see the benchmarks for that feature here under "sqlite-vec static", and it's competitive with faiss/usearch/duckdb https://alexgarcia.xyz/blog/2024/sqlite-vec-stable-release/i...
On the releases page https://github.com/asg017/sqlite-vec/releases/tag/v0.1.0 can you explain what is vec0.dll vs sqlite-vec-0.1.0-loadable-windows-x86_64.tar.gz, which also contains a similarly named vec0.dll but of a different size?
will fix up those links this weekend, thanks for pointing it out!
the cvec0.all file can be ignored. i was debugging a issue and uploaded a mscv compiled version as that, but its not part of the official release. prefer the tar.gz version and let me know if it doesn't work
Can't seem to make the loadable version work on Windows client (using .load and the latest x64 version of sqlite).
On Windows 10 it says "Error: the specified module could not be found."
On Windows 7 the error is more detailed and complains about missing libgcc_s_seh-1.dll which, according to a quick Google search, may or may not result from a compilation problem with MinGW...?
Great to see this. Seems simple enough, but I can't wait until ORMs like peewee incorporate support alongside things like FTS, etc. just for the sake of case of use.
No, libsql added custom vector search directly into their library, while sqlite-vec is a separate SQLite extension.
The libsql vector feature only works in libsql, sqlite-vec works in all SQLite versions. The libsql vector feature works kindof like pgvector, while sqlite-vec works more like the FTS5 full text SQLite extension.
I'd say try both and see which one you like more. sqlite-vec will soon be a part of Turso's and SQLite Cloud's products.
This isn't a complete extension, as mentioned in the README several times. I wanted a poc to use the new jiff library in SQL functions to test if it works. It did, so I put it in a repo for others to see. Definitely not production ready, it will change a lot in the future.
Also one note: load_extension isn't required, you can statically compile this and other extensions into an application. That being said, load_extension itself doesnt make your application 'vulnerable.' SQLite offers many features to limit and control dynamically loadable extensions, like sqlite3_enable_load_extension() and SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION. Of course it depends what your definition of "security" is, but load_extension() doesn't need to be dangerous.
Agreed, though the topic of timezone+DST support has come up a few times in the SQLite forums, and the SQLite team has never expressed much interest in it. Which I don't blame them, they would need to write it from scratch in C (for licensing reasons), and keep a timezone DB updates, which sounds like a nightmare.
I'm curious - do you find yourself constrained by the default macOS build often? Typically I `brew install sqlite` and use that CLI to get around extension loading issues (and for more modern SQLite versions). Same with Python's default MacOS build, which I avoid at all costs. Though very curious to hear more about times where that isn't a viable option
> do you find yourself constrained by the default macOS build often?
Only for about 10 minutes after a new install until I ...
> `brew install sqlite`
But I could understand that some people may not have that option (although I've yet to work at a place that locks macOS down that much, I've worked at places which locked down their Windows laptops down far more than that.)