Skip to content
Putting technology to work.
Insights to guide decisions and action.

Search articles

Trying vector search with vec1 in SQLite 3.54.0

Table of contents · 6 items

For developers who want to handle internal document search or RAG (retrieval-augmented generation) prototypes with SQLite embedded in their app instead of running a separate vector database, the arrival of the vector search extension "vec1" in the main SQLite repository is a topic of interest.

The version-3.54.0 tag dated October 9, 2026 includes the vec1 source and tests in ext/vec1/. However, a comment in the build configuration says it is "not included in the amalgamation (the single-file distribution source) or in any distribution package." Upgrading SQLite to 3.54.0 does not by itself make it available. In this article, we report its status as confirmed in the source and official documentation, and the results of building and running it in the editorial team's test environment.

vec1 is not bundled with SQLite; you build the extension yourself

The 3.54.0 build configuration (main.mk) contains the following comment about vec1.

vec1 loadable extension. Not part of the amalgamation or any distributed package; built only by explicitly running “make vec1.so”.

At the top of vec1.c, there is an example of building it as a loadable extension with gcc on x86_64 (gcc -O3 -DNDEBUG -mavx2 -mfma vec1.c -shared -fPIC -o vec1.so) and a pointer to the documentation page (sqlite.org/vec1). The version in the source is 0.8. It explains that building via main.mk can also make it detect at runtime whether the CPU supports AVX2.

In other words, you cannot use vec1 as-is with the sqlite3 command or the SQLite bundled with each language. You need to build the extension and load it on a connection that allows extension loading. vec1 is also not mentioned in the SQLite 3.54.0 release notes dated October 9, 2026.

The vec1 documentation page (sqlite.org/vec1) describes vec1 as an extension that performs approximate nearest neighbor search using SQLite's virtual table mechanism and supports Euclidean distance (L2) and cosine distance. The "current release" on the page is 0.7, a different version from the source in the 3.54.0 tag (0.8). The future plans section says "testing is insufficient," and it is at a pre-1.0 stage.

We built and ran it in the editorial team's test environment

On October 14, 2026, we tested it in the following environment.

ItemDetails
OS・CPULinux x86_64, Intel Xeon 2.10GHz (4 cores)
vec1Built ext/vec1/vec1.c from the version-3.54.0 tag with gcc -O3 -DNDEBUG -mavx2 -mfma
SQLite3.54.0 (bundled with the Python library apsw 3.54.0.0)

We loaded it from apsw, which includes SQLite 3.54.0, rather than Python's SQLite (3.45.1 in this environment). We did not test whether it works with older SQLite. After loading, SELECT vec1_info() returned version 0.8 (AVX2, multi-threaded).

The SQL we used follows the style of the test file (ext/vec1/test/).

-- ベクトル列と、任意の付随データ列(ここでは文書名)を持つ仮想表
CREATE VIRTUAL TABLE docs USING vec1(vector, title);

INSERT INTO docs(rowid, vector, title)
  VALUES (1, vec1_from_json('[1,0,0,0]'), '請求書の発行手順');

-- 全件を比べる索引(flat)で作り直す
INSERT INTO docs(cmd, vector) VALUES ('rebuild', '{index:"flat"}');

-- 問い合わせのベクトルに近い3件
SELECT rowid, title, distance
  FROM docs(vec1_from_json('[1,0.05,0,0]'), '{K:3}');

We inserted five 4-dimensional vectors as a test and confirmed the following.

  • CREATE VIRTUAL TABLE created six auxiliary objects (tables and indexes on sqlite_master): docs_base, docs_config, docs_idx, docs_idx_idx, docs_meta and docs_model
  • Search returned results even before rebuild, and they were the same as after rebuild (flat)
  • distance was the squared Euclidean distance (the function reference also describes vec1_l2_distance as "the square of the Euclidean distance"). For vectors differing by 0.05 it returned 0.0025, and vec1_l2_distance comparing orthogonal unit vectors returned 2.0. vec1_cos_distance was 1.0
  • PRAGMA integrity_check was ok

If you use the distance directly as a threshold, you need to set it on the assumption that it is a squared value.

Approximate search trained with only codesize 16 had a low match rate

To speed things up as the number of rows grows, vec1 also offers an approximate nearest neighbor (ANN) index trained on the data. You create the training result with vec1_train and then rebuild using that result.

-- 学習(codesize は圧縮後の大きさの指定)
SELECT vec1_train(vector, '{codesize:16}') FROM big;
-- 得られた学習結果で索引を作り直す(? に上の結果を渡す)
INSERT INTO big(cmd, vector) VALUES ('rebuild', ?);

We generated 20,000 random 384-dimensional vectors scattered around 200 centers and compared the top 10 results for 20 queries. Treating the exhaustive search (flat) results as ground truth, we measured how many of the same items the approximate search returned (match rate).

Results of testing vec1 in SQLite 3.54.0 in the editorial team's test environment. Top-10 search on 20,000 vectors with 384 dimensions and 20 queries. Exhaustive search (flat) took a median of 4.42 ms per query. Approximate search trained with only codesize 16 specified (PQ compression only, nbucket at the default of 0) was fast at 0.27 ms, but its average match rate against exhaustive search was 0.14, and it stayed at 0.14 even when nprobe was changed. Training took 1.27 seconds. The data was randomly generated, not embeddings of real documents

Search methodPer query (median)Top-10 match rate (average)
Exhaustive search (flat)4.42 msUsed as ground truth
Approximate search (codesize 16 only, nprobe default 0.05)0.27 ms0.14
Same (nprobe 0.2 specified)0.16 ms0.14
Same (nprobe 1.0 specified)0.15 ms0.14

Training took 1.27 seconds and rebuilding the index took 0.40 seconds. Approximate search was more than an order of magnitude faster than exhaustive search, but on average only 1.4 of the top 10 results matched the ground truth. Raising nprobe, which widens the search scope, did not change the match rate.

When we later compared this with the official documentation (checked on October 16, 2026), our settings had deviated from the recommendations.

  • We were not using bucket partitioning. The reference says that nbucket of vec1_train (how many groups to split the data into for searching) defaults to 0, and when it is 0, no partitioning is done and all compressed vectors are scanned. Since we did not specify nbucket, we were not using the mechanism through which nprobe (the fraction of groups to search) takes effect at all. This is likely why the match rate did not change with nprobe
  • The compression may have been too aggressive. According to the documentation, the guideline for codesize in the pq compression method is 1/8 or 1/16 of the number of dimensions (48 or 24 for 384 dimensions). Our value of 16 was smaller than that. The documentation also recommends the opq method for recent embeddings

We did not re-measure with different settings, so we have not confirmed how much the match rate improves with the recommended settings. This is a single result on randomly generated data, and the same may not hold for embeddings of real documents.

What to check first if you are considering adoption

From here on are the editorial team's suggestions.

  1. Whether you can distribute the extension. Check whether you can build and deploy the extension in your production runtime and allow it to be loaded. It cannot be used with managed databases or in environments that do not allow loading extensions
  2. Whether your data size is small enough for exhaustive search. Under our conditions, exhaustive search on 20,000 vectors with 384 dimensions took 4 to 5 ms per query. For internal document search, first measure whether flat meets your requirements, and consider approximate search only when it becomes necessary
  3. Measure the match rate of approximate search on your own data. Specify nbucket explicitly, start codesize from the guideline on the documentation page, and compare by varying codesize, nbucket and nprobe with exhaustive search results as ground truth. Do not choose settings based on speed alone
  4. Store the original text and embeddings separately. vec1 is at a pre-1.0 stage, and the auxiliary table format also has a version number. Make sure you can recover if an extension update requires rebuilding

If you can use PostgreSQL, Running pgvector in production is also an option. For overall search design, see RAG optimization patterns, and for setting assumptions when using SQLite in business systems, see The SQLite bug that went unnoticed for 16 years.

Scope of verification

On October 14, 2026, we retrieved the version-3.54.0 tag (the "Version 3.54.0" commit from October 9, 2026) from the SQLite mirror on GitHub (sqlite/sqlite) and read parts of main.mk, ext/vec1/vec1.c, ext/vec1/Makefile and ext/vec1/test/. We then built vec1.c in the environment above, loaded it from apsw 3.54.0.0 (SQLite 3.54.0) and ran it (hands-on testing). On October 16, we reviewed the SQLite 3.54.0 release notes and the vec1 documentation, usage guide, function reference and test results pages (sqlite.org/vec1) (document research). The data was randomly generated, and we did not test embeddings of real documents, behavior on Windows, macOS, ARM or older SQLite, approximate search with nbucket specified, or comparisons varying codesize.

If you are considering how to integrate internal document search or RAG into existing systems, contact us through Consultation on development, AI, and automation.

References

Share this articleXFacebook
Kakeru Suzuki

Fascinated by the possibilities of technology, has had a deep interest in programming and digital art since student days

Turn this article's theme into your company's next step

Concrete steps forward for your organization.

We organize your desired architecture, legacy systems, and operational requirements to formulate your next steps toward execution.

  • Desired architecture
  • Integration with existing environments
  • Operational requirements
Consult on development & operations initiatives

You can consult with us from the initial conceptual stage. Details from this article will be carried over to the inquiry form.

Receive the latest articles by email