sqlite-vec

sqlite-vec is a lightweight SQLite extension for vector similarity search. It enables storing and querying vector embeddings directly in SQLite databases without external vector databases.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "sqlite-vec" with this command: npx skills add existential-birds/beagle/existential-birds-beagle-sqlite-vec

sqlite-vec

sqlite-vec is a lightweight SQLite extension for vector similarity search. It enables storing and querying vector embeddings directly in SQLite databases without external vector databases.

Quick Reference

Load Extension

import sqlite3 import sqlite_vec from sqlite_vec import serialize_float32

db = sqlite3.connect(":memory:") db.enable_load_extension(True) sqlite_vec.load(db) db.enable_load_extension(False)

Basic KNN Query

-- Create table CREATE VIRTUAL TABLE vec_items USING vec0( embedding float[4] );

-- Insert vectors (use serialize_float32() in Python) INSERT INTO vec_items(rowid, embedding) VALUES (1, X'CDCCCC3DCDCC4C3E9A99993E00008040');

-- KNN query SELECT rowid, distance FROM vec_items WHERE embedding MATCH '[0.3, 0.3, 0.3, 0.3]' AND k = 10 ORDER BY distance;

Core Concepts

Vector Types

sqlite-vec supports three vector element types:

float[N] - 32-bit floating point (4 bytes per element)

  • Most common for embeddings (OpenAI, Cohere, etc.)

  • Example: float[1536] for text-embedding-3-small

int8[N] - 8-bit signed integers (1 byte per element)

  • Range: -128 to 127

  • Used for quantized embeddings

bit[N] - Binary vectors (1 bit per element, packed into bytes)

  • Most compact storage

  • Used for binary quantization

Binary Serialization Format

Vectors must be provided as binary BLOBs or JSON strings. Python helper functions:

from sqlite_vec import serialize_float32, serialize_int8 import struct

Float32 vectors

vector = [0.1, 0.2, 0.3, 0.4] blob = serialize_float32(vector)

Equivalent to: struct.pack("%sf" % len(vector), *vector)

Int8 vectors

int_vector = [1, 2, 3, 4] blob = serialize_int8(int_vector)

Equivalent to: struct.pack("%sb" % len(int_vector), *int_vector)

NumPy arrays can be passed directly (must cast to float32):

import numpy as np embedding = np.array([0.1, 0.2, 0.3, 0.4]).astype(np.float32) db.execute("SELECT vec_length(?)", [embedding])

vec0 Virtual Tables

The vec0 virtual table is the primary data structure for vector search.

Basic Table Creation

CREATE VIRTUAL TABLE vec_documents USING vec0( document_id integer primary key, contents_embedding float[768] );

Distance Metrics

CREATE VIRTUAL TABLE vec_items USING vec0( embedding float[768] distance_metric=cosine );

Supported metrics: l2 (default), cosine , hamming (bit vectors only)

Column Types

vec0 tables support four column types:

  • Vector columns - Store embeddings (float[N], int8[N], bit[N])

  • Metadata columns - Indexed, filterable in KNN queries

  • Partition key columns - Internal sharding for faster filtered queries

  • Auxiliary columns - Unindexed storage (prefix with +)

Example with all column types:

CREATE VIRTUAL TABLE vec_knowledge_base USING vec0( document_id integer primary key,

-- Partition keys (sharding) organization_id integer partition key, created_month text partition key,

-- Vector column content_embedding float[768] distance_metric=cosine,

-- Metadata columns (filterable in KNN) document_type text, language text, word_count integer, is_public boolean,

-- Auxiliary columns (not filterable) +title text, +full_content text, +url text );

KNN Queries

Standard Query Syntax

SELECT rowid, distance FROM vec_items WHERE embedding MATCH ? AND k = 10 ORDER BY distance;

Key components:

  • WHERE embedding MATCH ?

  • Triggers KNN query

  • AND k = 10

  • Limit to 10 nearest neighbors

  • ORDER BY distance

  • Sort results by proximity

Metadata Filtering

SELECT document_id, distance FROM vec_movies WHERE synopsis_embedding MATCH ? AND k = 5 AND genre = 'scifi' AND num_reviews BETWEEN 100 AND 500 AND mean_rating > 3.5 AND contains_violence = false ORDER BY distance;

Supported operators on metadata: = , != , > , >= , < , <= , BETWEEN

Not supported: IS NULL , LIKE , GLOB , REGEXP , scalar functions

Partition Key Filtering

SELECT document_id, distance FROM vec_documents WHERE contents_embedding MATCH ? AND k = 20 AND user_id = 123 -- Partition key pre-filters ORDER BY distance;

Partition keys enable multi-tenant or temporal sharding. Best practices:

  • Each unique partition value should have 100+ vectors

  • Use 1-2 partition keys maximum

  • Avoid over-sharding (too many unique values)

Joining with Source Tables

WITH knn_matches AS ( SELECT document_id, distance FROM vec_documents WHERE contents_embedding MATCH ? AND k = 10 ) SELECT documents.id, documents.title, knn_matches.distance FROM knn_matches LEFT JOIN documents ON documents.id = knn_matches.document_id ORDER BY knn_matches.distance;

Distance Functions

For manual distance calculations (non-vec0 tables):

-- L2 distance SELECT vec_distance_l2('[1, 2]', '[3, 4]'); -- 2.8284...

-- Cosine distance SELECT vec_distance_cosine('[1, 1]', '[2, 2]'); -- ~0.0

-- Hamming distance (bit vectors) SELECT vec_distance_hamming(vec_bit(X'F0'), vec_bit(X'0F')); -- 8

Vector Operations

Constructors

-- Float32 SELECT vec_f32('[.1, .2, .3, 4]'); -- Subtype 223

-- Int8 SELECT vec_int8('[1, 2, 3, 4]'); -- Subtype 225

-- Bit SELECT vec_bit(X'F0'); -- Subtype 224

Metadata Functions

-- Get length SELECT vec_length('[1, 2, 3]'); -- 3

-- Get type SELECT vec_type(vec_int8('[1, 2]')); -- 'int8'

-- Convert to JSON SELECT vec_to_json(vec_f32('[1, 2]')); -- '[1.000000,2.000000]'

Arithmetic

-- Add vectors SELECT vec_to_json( vec_add('[.1, .2, .3]', '[.4, .5, .6]') ); -- '[0.500000,0.700000,0.900000]'

-- Subtract vectors SELECT vec_to_json( vec_sub('[.1, .2, .3]', '[.4, .5, .6]') ); -- '[-0.300000,-0.300000,-0.300000]'

Transformations

-- Normalize (L2 norm) SELECT vec_to_json( vec_normalize('[2, 3, 1, -4]') ); -- '[0.365148,0.547723,0.182574,-0.730297]'

-- Slice (for Matryoshka embeddings) SELECT vec_to_json( vec_slice('[1, 2, 3, 4]', 0, 2) ); -- '[1.000000,2.000000]'

-- Matryoshka pattern: slice then normalize SELECT vec_normalize(vec_slice(embedding, 0, 256)) FROM vec_items;

Quantization

-- Binary quantization (positive→1, negative→0) SELECT vec_quantize_binary('[1, 2, 3, 4, -5, -6, -7, -8]'); -- X'0F'

-- Visualize SELECT vec_to_json( vec_quantize_binary('[1, 2, -3, 4, -5, 6, -7, 8]') ); -- '[0,1,0,0,1,0,1,0]'

Iteration

-- Iterate through elements SELECT rowid, value FROM vec_each('[1, 2, 3, 4]'); /* ┌───────┬───────┐ │ rowid │ value │ ├───────┼───────┤ │ 0 │ 1 │ │ 1 │ 2 │ │ 2 │ 3 │ │ 3 │ 4 │ └───────┴───────┘ */

Python Integration

Complete Example

import sqlite3 import sqlite_vec from sqlite_vec import serialize_float32

Setup

db = sqlite3.connect(":memory:") db.enable_load_extension(True) sqlite_vec.load(db) db.enable_load_extension(False)

Create table

db.execute(""" CREATE VIRTUAL TABLE vec_items USING vec0( embedding float[4] ) """)

Insert vectors

items = [ (1, [0.1, 0.1, 0.1, 0.1]), (2, [0.2, 0.2, 0.2, 0.2]), (3, [0.3, 0.3, 0.3, 0.3]) ]

with db: for rowid, vector in items: db.execute( "INSERT INTO vec_items(rowid, embedding) VALUES (?, ?)", [rowid, serialize_float32(vector)] )

Query

query = [0.25, 0.25, 0.25, 0.25] results = db.execute( """ SELECT rowid, distance FROM vec_items WHERE embedding MATCH ? AND k = 2 ORDER BY distance """, [serialize_float32(query)] ).fetchall()

for rowid, distance in results: print(f"rowid={rowid}, distance={distance}")

Embedding API Integration

from openai import OpenAI from sqlite_vec import serialize_float32

client = OpenAI()

Generate embedding

response = client.embeddings.create( input="your text here", model="text-embedding-3-small" ) embedding = response.data[0].embedding

Store in sqlite-vec

db.execute( "INSERT INTO vec_documents(id, embedding) VALUES(?, ?)", [doc_id, serialize_float32(embedding)] )

Query

query_embedding = client.embeddings.create( input="search query", model="text-embedding-3-small" ).data[0].embedding

results = db.execute( """ SELECT id, distance FROM vec_documents WHERE embedding MATCH ? AND k = 10 """, [serialize_float32(query_embedding)] ).fetchall()

Performance Tips

  • Use partition keys for multi-tenant or temporally-filtered queries

  • Keep k reasonable (10-100 for most use cases)

  • Filter with metadata columns when possible

  • Choose appropriate distance metric for your embeddings

  • Batch operations in transactions

  • Use auxiliary columns for large data not needed in filtering

  • Ensure partition keys have 100+ vectors per unique value

Common Patterns

Multi-tenant Search

CREATE VIRTUAL TABLE vec_docs USING vec0( doc_id integer primary key, user_id integer partition key, embedding float[768] );

SELECT doc_id, distance FROM vec_docs WHERE embedding MATCH ? AND k = 10 AND user_id = 123;

Hybrid Search

SELECT product_id, distance FROM vec_products WHERE embedding MATCH ? AND k = 20 AND category = 'electronics' AND price < 1000.0 ORDER BY distance;

Matryoshka Embeddings

-- Adaptive dimensions: slice then normalize SELECT vec_normalize(vec_slice(embedding, 0, 256)) FROM vec_items;

Reference Files

  • setup.md - Installation, extension loading, Python bindings, NumPy integration

  • tables.md - vec0 table creation, column types, metadata/partition/auxiliary columns

  • queries.md - KNN query patterns, metadata filtering, partition filtering, optimization

  • operations.md - Vector operations, constructors, transformations, quantization, batch operations

Resources

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

tailwind-v4

No summary provided by upstream source.

Repository SourceNeeds Review
General

react-flow

No summary provided by upstream source.

Repository SourceNeeds Review
General

react-router-v7

No summary provided by upstream source.

Repository SourceNeeds Review