Vector indexes are an Upstash extension. They are not part of open-source Redis, and client libraries reach them through their generic command interface. They are also separate from Upstash Vector, which is a standalone vector database with its own API and SDKs.
A vector index stores embeddings under IDs and answers nearest-neighbour queries over them. It lives at an ordinary Redis key, so EXISTS, EXPIRE, and DEL apply to it, and a key already holding another type cannot be turned into one.
VECTOR.CREATE fixes two properties for the life of the index: DIM, the number of elements every vector must have, and METRIC, how similarity is measured. Use COSINE when only the direction of the embedding matters, which is the usual choice for text embeddings, DOT when magnitude carries meaning, and EUCLIDEAN when straight-line distance does. Neither can be changed afterwards; to change one, drop the index and create it again.
VECTOR.ADD upserts a vector under an ID and VECTOR.QUERY returns the nearest IDs with a score. Scores are normalized to 0 through 1 for every metric, so a higher score always means a closer match. Search is approximate: PROFILE moves a query along the recall and latency trade-off without changing anything stored.
Vectors can be given three ways. VALUES lists the elements as decimal numbers, FP32 takes the raw little-endian 32-bit float blob, and BASE64-FP32 takes that blob base64-encoded, which is the form that survives the JSON body of the REST API.
SDK support#
No client library has typed helpers for these commands yet, the Upstash @upstash/redis and upstash-redis SDKs included. Send them through the generic command interface: redis.call("VECTOR.QUERY", ...) in ioredis, client.sendCommand(["VECTOR.QUERY", ...]) in node-redis, client.execute_command("VECTOR.QUERY", ...) in redis-py, client.Do(ctx, "VECTOR.QUERY", ...) in go-redis, and redis::cmd("VECTOR.QUERY") in redis-rs.
REST API usage#
Vector commands work over the REST API like any other command, as a JSON array where each element is one token of the command. Since the body is JSON, pass binary vectors as BASE64-FP32 rather than FP32.