This page is intended to be a complete reference to the interface exported by the vec1 extension. It is not a user manual. For that, please see this page.
Vec1's native vector format is an SQL BLOB containing a packed array of 32-bit IEEE floating point values in machine byte order. All values must be finite, NaN and infinite values are not allowed.
Vec1 provides the following SQL scalar functions:
This function returns a human-readable string describing the version of the vec1 extension currently in use.
Both arguments must be vectors in native format. Both must be the same size. This function returns the square of the euclidean distance between the two vectors (SQL type real), calculated as:
vec1_l2_distance(a, b) = ∑i(ai - bi)2
If either argument is not an SQL BLOB, or if the two arguments are of different sizes, or if the size in bytes of the two arguments is not divisible by 4, an exception is thrown.
Like vec1_l2_distance(), except that it returns the cosine
distance between the two vectors (SQL type real), calculated as follows:
vec1_cos_distance(a, b) = 1.0 - ∑i(ai bi) / √((∑i ai2)(∑i bi2))
The value returned is always in the range 0.0 to 2.0. A value of 0.0 indicates that the vectors point in the same direction. 1.0 indicates that they are orthogonal. A value of 2.0 means the two vectors point in opposite directions.
This function does not require its arguments to be normalized.
The argument to this function must be a vector in native format. A JSON array containing the elements of the vector is returned (SQL type TEXT).
The argument to this function must be a JSON array of numeric values. It returns the equivalent vector in native format (a BLOB).
The first form returns the current value of parameter PARAMETER (type TEXT). The second form sets the value of PARAMETER to VALUE, then returns a copy of the new value. Supported parameters are currently:
nthread. Integer. The number of threads to use for
various operations, including the main thread. The default value is 1.nprobe. Real. The default nprobe value
to use for queries against vec1 tables. Default value 0.05.Example
To configure vec1 to use 16 threads when possible:
SELECT vec1_config('nthread', 16);
To query for the current default value of nprobe:
SELECT vec1_config('nprobe');
The IVF+OPQ algorithm used by vec1 requires a trained model. This model is built by training on a representative set of vectors (i.e. vectors with the same data distribution as those that will be indexed).
There is a single aggregate SQL function used for training:
The aggregate should be run over the set of training vectors, each vector passed as the first argument. It returns a BLOB containing the trained model, which may be used with a vec1 virtual table. The second argument is a JSON object (type TEXT) containing parameters to configure the model and training process. The following parameters are supported to configure the model:
distance. The distance metric to use. Must be either
"l2" or "cos". The default is "l2".nbucket. Integer. The number of buckets used by
the inverted file (IVF). If set to 0, IVF is disabled and queries perform
an exhaustive search over all (possibly compressed) vectors.quantizer. A string identifying the quantizer to
use to compress vectors within each bucket. There are four possible values:
codesize. Integer. The size in bytes of the
quantized vectors. This is advisory only - because not all sizes can
be implemented by all quantizers, in practice vec1 picks the nearest
possible size to the specified value.
The default value depends on the value of the "quantizer" field. If quantizer is set to "none", this value defaults to 0. If it is set to "pq" or "bq", the default of this value is 1 byte for each 8 vector dimensions (rounded up). Or, if quantizer is set to "opq", this value defaults to 32.
Explicitly setting this value to 0 behaves in the same way as not setting it at all - the actual value used will be the default as determined by the "quantizer" field.
residual. Boolean. If true and both
nbucket and codesize are greater than 0, then
residual instead of full vectors are compressed and stored in the index.
The default is true.wht. Boolean. If true, a randomized Walsh-Hadamard
transformation is applied to all data and query vectors before processing.
The default is true if quantizer is set to "bq", or false otherwise.And the following parameters are also supported to configure the training process itself:
progress. The name of an SQL function registered
with the database connection. During training, it is invoked periodically
as if by:
SELECT progress(:percent, :msg);
:percent) is an integer indicating the
approximate percentage of work completed. The second (:msg)
is a human-readable message describing the current stage in English.profile. The name of an SQL function registered
with the database connection. It is invoked during training as if by:
SELECT profile(:json);
:json) is a json object containing
a series of attributes that allow performance profiling of the training
algorithm. The attributes of the object and the number of times the profile
callback is invoked during training are not strictly defined and may change
between versions. They are intended to be reasonably intuitive though.
nthread. Integer. The number of CPU threads to use
for training, including the main thread. If not specified, the default
configured via vec1_config() is used. If no default is
set, training is single-threaded.nopq_round. Integer. The number of iterations of
the OPQ algorithm to use to calculate a rotation, if it is enabled. The
default value is 5.svd_verify. Boolean. If true, additional checks are
performed on each Singular Value Decomposition (SVD) computed during OPQ
training. This is computationally expensive and should only be enabled
when debugging. Default: false.opq. Boolean. Now deprecated in favor of
quantizer:"opq".
Models may be generated on one machine and used on another. However, the two machines must use the same byte-order for 32-bit IEEE floating point values.
Example
Assume table "learn" contains one training vector per row in column "vec". The following query generates a model:
-- Returns a model (an SQL BLOB) for use with a vec1 virtual table.
--
-- Configuration:
-- distance = "cos" -> use cosine distance
-- quantizer = "opq" -> use OPQ to compress vectors
-- codesize = 32 -> compress each vector to 32 bytes
-- nbucket = 1024 -> use 1024 IVF buckets
--
SELECT vec1_train(learn.vec, '{
distance: "cos",
quantizer: "opq",
codesize: 32,
nbucket: 1024
}')
FROM learn;
To create a vec1 virtual table:
CREATE VIRTUAL TABLE tbl USING vec1(vector_column, metadata_column...);
The first argument specifies the name of the column used to store vectors. Each subsequent argument specifies the name of a metadata column.
A vec1 table must contain exactly one vector column, and may contain between 0 and 255 metadata columns. All vec1 tables have a unique integer rowid that identifies each row. Additionally, all vec1 tables have a hidden column named "distance" populated dynamically by nearest-neighbor queries.
Column names may be enclosed in single or double quotes. If unquoted, they must consist only of ASCII alphanumeric characters and underscores. The names "rowid" and "distance" are reserved and may not be used.
It is not possible to specify types or other column constraints for vec1 table columns.
Vec1 virtual tables may be modified using standard SQL INSERT, UPDATE, and DELETE statements. The vector column accepts only BLOB values whose length is a multiple of 4 bytes (each element is a 32-bit floating-point value). Once the vector size for a table has been fixed, all inserted vectors must have exactly that size.
The vector size is fixed when either:
Metadata columns may store values of any type.
A vec1 table may be configured to use a model using the following SQL command:
INSERT INTO tbl(cmd, arg) VALUES('rebuild', MODEL);
MODEL must either be a BLOB returned by vec1_train(), or else a JSON object (type TEXT) specifying model parameters. Supported model parameters for JSON models are:
distance. Text. Must be set to either
"l2" or "cos" to specify the distance metric to be used by the table.
index. Text. Must be set to either "none"
or "flat". A "none" index stores each vector in its own row of an
SQLite table. The only reason to explicitly configure a "none" index
is to set the distance metric. A "flat" index stores all vectors in
large packed SQL BLOBs. This can provide a 2x performance improvement
over storing each vector in its own row.
The 'rebuild' command automatically rebuilds the index using the new model. Subsequent 'rebuild' commands replace the existing index. 'rebuild' may be run before or after vectors are added to the table.
Example
To configure a vec1 table to store full vectors in packed BLOBs and to use cosine distance when queried:
INSERT INTO tbl(cmd, arg) VALUES('rebuild', '{
index: "flat",
distance: "cos"
}');
A vec1 table is queried for the nearest-neighbors of a vector by using the table as a table-valued function, where the first argument is the query vector, and the second, optional, argument the query parameters. As follows:
SELECT ... FROM tbl(VECTOR, PARAMETERS)
If PARAMETERS is passed a TEXT value, it is interpreted as a JSON object containing query parameters. The following query parameters are supported:
K. Integer. The number of results required. This
must be set to a value between 0 and 33554432 (225).
nprobe. A real value. This value must be greater
than 0.0. If a value less than 1.0 is specified, then it is the fraction
of IVF buckets that should be searched for nearest-neighbors. If the
value is 1.0 or greater, it is truncated to an integer and used as the
number of buckets to scan searching for nearest-neighbors. If this
parameter is not specified, the connection-wide default configured by
vec1_config() is used. If no default has been
configured, 0.05 is used.
streaming. Boolean. If this parameter is false (the
default), then K and nprobe are both hard limits -
the virtual table will never return more than K results or scan
more than nprobe buckets. If streaming is set to
true, then these parameters are both advisory, and the virtual table
continues to return results until the SQL engine stops requesting them.
The hidden "distance" column is populated with the distance between the query vector and the row vector for each row returned. If the table is configured with a model that uses compressed vectors (i.e. was trained with a non-zero "codesize" parameter), then the distances returned in this column are based on the compressed version of the vector. For non-streaming queries, rows are always returned in ascending order of this column.
For streaming queries, rows are usually returned in ascending order of "distance", but some results may also be returned slightly out of order. This happens when the SQL engine requests so many rows that the query has to begin scanning more than the number of buckets suggested by the "nprobe" parameter.
If PARAMETERS is passed an INTEGER value instead of TEXT, it is equivalent to specifying the integer as the "K" value and leaving all other query parameters unset.
WHERE clause processing
If a nearest-neighbor query has a WHERE clause that specifies one or more constraints connected by AND operators that meet the following criteria, then they are evaluated internally by vec1. This changes the query results because this filtering occurs before the best "K" results are accumulated. The criteria are:
LIMIT clause processing
Normally, a nearest-neighbor query requires a "K" value to be specified. However, if a query against a vec1 table has a visible LIMIT clause, then the value passed to the LIMIT clause is used in place of an explicit "K". Or, if a query has both an explicit "K" and a visible LIMIT clause, then the smaller of the two values is selected at runtime. Whether or not an SQL LIMIT clause is visible is determined by the SQL engine. In general, a LIMIT clause is visible if the query (or sub-query) that uses the vec1 table:
This page was last updated on 2026-10-01 11:21:38Z