Claude Academy
Sign in

Turso/libSQL Native Vector Search

libSQL (Turso's SQLite fork) ships vector search natively in the core engine — no extension to load, unlike pgvector on Postgres or sqlite-vec on stock SQLite. Vectors are just a column type, present in every Turso database and every embedded replica (see local-first-databases).

Column types

Declare dimensionality in the type; max 65,536 dimensions:

TypeStorageUse
F32_BLOB(n)4 bytes/dimRecommended default
F64_BLOB(n)8 bytes/dimExtra precision, rarely needed
F16_BLOB(n) / FB16_BLOB(n)2 bytes/dimHalf-precision (IEEE / bfloat16) compression
F8_BLOB(n)1 byte/dimAggressive compression
F1BIT_BLOB(n)1 bit/dimBinary quantization
CREATE TABLE docs (
  id INTEGER PRIMARY KEY,
  content TEXT,
  embedding F32_BLOB(768)
);
INSERT INTO docs VALUES (1, 'hello', vector32('[0.01, 0.02, ...]'));
SELECT vector_extract(embedding) FROM docs WHERE id = 1;

vector32('[...]') converts a JSON-style text vector to the binary format; vector_extract() converts back for inspection.

Exact (brute-force) search

Named distance functions, not operators (contrast supabase-pgvector):

SELECT id, content
FROM docs
ORDER BY vector_distance_cos(embedding, vector32('[...]')) ASC
LIMIT 5;
  • vector_distance_coscosine distance = 1 − cosine similarity, so 0 is identical and smaller is closer; hence ASC.
  • vector_distance_l2 — Euclidean; not available for 1-bit vectors.

Exact scan is O(rows) but exactly correct — fine for thousands to low hundreds of thousands of rows.

ANN with DiskANN

For large tables, create an approximate index using the DiskANN algorithm (disk-based graph index, in contrast to pgvector's in-memory-oriented HNSW):

CREATE INDEX docs_idx ON docs (libsql_vector_idx(embedding));

Query via the table-valued function vector_top_k, then JOIN back on rowid:

SELECT d.id, d.content
FROM vector_top_k('docs_idx', vector32('[...]'), 5) AS t
JOIN docs d ON d.rowid = t.id;

Details that bite:

  • Partial indexes are supported (... WHERE deleted = 0).
  • Index settings pass as variadic strings: libsql_vector_idx(embedding, 'metric=l2', 'compress_neighbors=float8'). Tuning defaults: alpha=1.2, search_l=200, insert_l=70.
  • Vector indexes require a ROWID table or a single non-composite primary key — composite-PK and WITHOUT ROWID tables can't be indexed.

vs pgvector

libSQL vectorspgvector
Packagingbuilt into enginePostgres extension (create extension vector)
Query syntaxnamed functions (vector_distance_cos)operators (<->, <=>, <#>)
ANN algorithmDiskANNHNSW, IVFFlat
Deployment shapeembeddable, edge, offline replicasclient-server

Rule of thumb: your data layer picks your vector store. Already on Postgres/Supabase → pgvector. Need embedded/edge/offline (local-first-databases) → libSQL. The rag-fundamentals pipeline above the store is identical either way.

Key terms

  • libSQL — Turso's open-contribution SQLite fork; vector search is native in the engine, no extension required.
  • F32_BLOB(n) — the recommended vector column type: n-dimensional float32, up to 65,536 dimensions.
  • vector32() / vector_extract() — conversion functions between text vector literals and the binary column format, and back.
  • vector_distance_cos — cosine-distance function (1 − cosine similarity); order ASC because smaller means more similar.
  • DiskANN — the disk-based approximate-nearest-neighbor graph algorithm behind libSQL vector indexes.
  • libsql_vector_idx — the indexing expression used in CREATE INDEX to build a DiskANN index over a vector column; accepts variadic string settings like 'metric=l2'.
  • vector_top_k — table-valued function that queries a vector index for the k nearest rows, joined back to the base table on rowid.
  • compress_neighbors — index setting that stores neighbor vectors compressed (e.g. float8) to shrink the DiskANN graph.
  • ROWID-table requirement — vector indexes only work on tables with rowids or a single non-composite primary key.
  • Cosine distance — 1 − cosine similarity; the identity linking libSQL's distance output to similarity scores used elsewhere.

See also