Vault / wiki/401/turso-vector-search.md
updated 2026-07-16Turso/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:
| Type | Storage | Use |
|---|---|---|
F32_BLOB(n) | 4 bytes/dim | Recommended default |
F64_BLOB(n) | 8 bytes/dim | Extra precision, rarely needed |
F16_BLOB(n) / FB16_BLOB(n) | 2 bytes/dim | Half-precision (IEEE / bfloat16) compression |
F8_BLOB(n) | 1 byte/dim | Aggressive compression |
F1BIT_BLOB(n) | 1 bit/dim | Binary 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_cos— cosine distance = 1 − cosine similarity, so 0 is identical and smaller is closer; henceASC.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 vectors | pgvector | |
|---|---|---|
| Packaging | built into engine | Postgres extension (create extension vector) |
| Query syntax | named functions (vector_distance_cos) | operators (<->, <=>, <#>) |
| ANN algorithm | DiskANN | HNSW, IVFFlat |
| Deployment shape | embeddable, edge, offline replicas | client-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
- supabase-pgvector — the Postgres counterpart
- local-first-databases — where embedded vector search pays off
- rag-fundamentals — the pipeline above the store