Skip to content

Stores and indexes

Reference for the store verbs, the index verbs, the record shape, and the score each provider returns.

A store owns the index lifecycle and hands out index handles. An index handle is scoped to one namespace and owns the record verbs. Every verb returns a Result, either { ok: true, value } or { ok: false, error }. Provider failures never throw.

Store

Create a store with the adapter for your provider: createQdrantStore, createPgvectorStore, createPineconeStore, createSupabaseStore, createUpstashStore, createVectorizeStore, or createRedisStore. Each takes the native client under client.

MethodDescription
createIndex({ name, dimension, metric? })Creates a collection, table, index, or namespace. metric is cosine (default), euclidean, or dot.
deleteIndex(name)Drops the index and every record in it. Returns not_found if the index does not exist.
listIndexes()Returns the index names.
index(name, { namespace? })Returns an index handle scoped to one namespace.
provider"qdrant", "pgvector", "pinecone", "supabase", "upstash", "vectorize", or "redis".
rawThe client you passed in, with its original type.

Index

Every provider gets namespaces. Pinecone and Vectorize have them natively. On Qdrant, pgvector, Supabase, Upstash, and Redis the adapter emulates them, as described on each provider page.

MethodDescription
upsert(records)Inserts or replaces records by id. Large batches are sent as several provider requests, four at a time. If one fails, no further request starts, the ones already in flight finish, and the call returns the error. Redis sends one 500-record batch after another and stops at the first batch that fails. Retry the whole call, because an upsert replaces by id.
query({ vector, topK, filter?, includeMetadata?, includeVector? })Returns the nearest records with a score.
fetch(ids, { includeVector? })Returns the records that exist, in request order.
delete({ ids }), delete({ filter }), delete({ all: true })Removes records in the namespace. A selector that names none of the three, or an empty ids list, returns invalid_argument and deletes nothing.

Records

interface VectorRecord {
  readonly id: string;
  readonly vector: readonly number[];
  readonly metadata?: Metadata;
}

type MetadataValue = string | number | boolean | string[];
type Metadata = Readonly<Record<string, MetadataValue>>;

Metadata values are string, number, boolean, or string[]. That is the intersection of what the seven providers accept. Each adapter adds a few rules of its own. Qdrant and Upstash in metadata mode reject metadata under _id or _namespace, and Vectorize rejects metadata under _id. All three reject a namespace that holds /, and Upstash in metadata mode also rejects one that holds a backslash or both quote characters. Redis rejects a value whose type contradicts the declared field type, and an index name that holds :.

Scores

Qdrant, pgvector, Pinecone, and Vectorize return the provider's native score for the index metric. Higher is better for cosine and dot, and lower is better for euclidean. Upstash normalizes every metric to the range 0 to 1, where higher is always better. Redis returns a distance for every metric, where lower is closer.

MetricQdrantpgvector and SupabasePineconeUpstashVectorizeRedis
cosineSimilarity, higher is better1 - distance, higher is betterSimilarity, higher is better(1 + similarity) / 2, higher is betterSimilarity, higher is better1 - similarity, lower is better
dotDot product, higher is betterDot product, higher is betterDot product, higher is betterNormalized, higher is betterDot product, higher is better1 - dot product, lower is better
euclideanDistance, lower is betterDistance, lower is betterSquared distance, lower is better1 / (1 + squared distance), higher is betterDistance, lower is betterDistance, lower is better

A score threshold tuned on one provider does not carry over to another. Check it against real data after a move.

On this page