Skip to main content

Indexes and points

This page is the complete data model for VectorDB: what an index is, what a point is, every setting you choose at creation time, and — just as important — which settings can never change afterward.

Index

An index is a named container for vectors. Everything in one index shares two things:

  • one fixed width (the number of dimensions in every vector), and
  • one distance metric (the rule for measuring how close two vectors are).

Other vector databases call this a "collection" (Qdrant, Pinecone-style products) or an "index" (Vertex AI, Azure AI Search). On this platform, the customer-facing resource is the index; the word collection refers to the internal storage name, explained below.

Names

Index names must match [a-z0-9]([a-z0-9-]*[a-z0-9])? — lowercase letters, digits, and hyphens, starting and ending with a letter or digit, at most 48 characters. Uppercase letters and underscores are refused. Real rejection messages:

{"error":"index name \"My_Index\" must match [a-z0-9]([a-z0-9-]*[a-z0-9])? - lowercase letters, digits and hyphens, starting and ending with an alphanumeric","request_id":"..."}
{"error":"index name \"...\" is longer than 48 characters","request_id":"..."}

The internal collection name

Every read of an index reports a collection field like p_k3xq9m_docs. That is the storage name the platform derived from your project plus your index name, so two projects can both own an index named docs. It is reported so you can recognize your data (for example, through direct engine access); it is never accepted as input anywhere.

Dimensions

dimensions is how many numbers each vector holds. Range 1–65536; omit it (or send 0) and it defaults to 1536, a common embedding-model output size. Every vector you ever write must have exactly this many numbers.

Choose it by looking at your embedding model's documentation — the model's output size is your index's dimensions. Get it wrong and every upsert fails with a dimension-mismatch error (see the quickstart's failure example).

Out-of-range values are rejected at creation:

{"error":"dimensions must be between 1 and 65536, or omit it for the default of 1536","request_id":"..."}

Distance metrics

The distance metric defines "close". It accepts these values, case-insensitively:

MetricAliasesWhat it measuresWhen to pick it
cosine (default)The angle between vectors, ignoring their lengthThe usual choice for text embeddings; most embedding models are trained for it
dotdotproduct, dot_productThe inner product (direction and length)When your model's docs say to use dot product / inner product
euclideuclidean, l2Straight-line distance between the pointsWhen your model's docs say to use Euclidean or L2 distance

Anything else is rejected:

{"error":"distance must be one of \"cosine\", \"dot\" or \"euclid\"","request_id":"..."}

Advanced creation options

These are for tuning memory and durability trade-offs. The defaults are fine for most workloads; the console keeps them behind an "Advanced options" disclosure for a reason.

FieldDefaultWhat it does
on_diskfalseStore vectors on disk instead of RAM. Cheaper for big indexes, slower to search.
payload_on_diskfalseStore payloads on disk instead of RAM.
quantization.kindnoneCompress vectors to save memory at a small accuracy cost. scalar (alias int8) or binary.
quantization.quantileScalar-quantization tuning value, e.g. "0.99".
quantization.always_ramfalseKeep the compressed copy in RAM even when vectors are on disk.
shards1How many pieces the index is split into.
replicas1How many copies exist. Range 1–8.

Invalid quantization kinds are rejected with:

{"error":"quantization.kind must be one of \"none\", \"scalar\" or \"binary\"","request_id":"..."}

Index lifecycle and status

Creating an index returns HTTP 201 immediately with state: "pending" — the storage is built asynchronously. Poll GET .../indexes/{name} until ready: true. Data operations before that return 409 index is not ready yet; its collection has not been created.

FieldMeaning
stateCoarse phase: pending, creating, ready, degraded, conflict, or blocked
readyThe authoritative "you can use it now" boolean
collection_statusThe engine's own health word — green, yellow, red, or grey — present once storage exists
points_count, vectors_count, segments_countLive size counters
messageHuman-readable explanation when something is wrong (for example, why a conflict happened)

What can change, and what can't

Only two fields are editable after creation, via PATCH (project admin role required):

{"replicas": 2, "payload_on_disk": true}

replicas must be 1–8 (replicas must be between 1 and 8 otherwise). Everything else is immutable, and the API tells you why instead of just saying no:

Field you tried to changeExact 400 error
dimensionsdimensions is immutable: existing points cannot be re-embedded, so a different width is a new index, not an edit
distancedistance is immutable: the metric is baked into the graph built over the existing points
shardsshards is immutable: resharding moves data and is not performed on a spec edit
on_diskon_disk is immutable: vectors are not restaged between memory and disk in place
quantizationquantization is immutable: it is fixed when the collection is built
(empty patch)no mutable fields to change; the editable fields are replicas and payload_on_disk
There is no "resize"

To change dimensions, distance, or any other immutable setting, create a new index and re-ingest your data yourself. The platform does not migrate points between indexes, and deleting an index (HTTP 204) permanently destroys every point in it — there are no snapshots or backups in alpha.

Points

A point is one entry in an index. It has up to three parts:

{"id": 42, "vector": [0.1, 0.2, 0.3, 0.4], "payload": {"tag": "alpha", "source": "manual"}}

Vector (required)

The list of numbers. Its length must equal the index's dimensions exactly. One dense vector per point — VectorDB does not support named or sparse vectors.

Id (optional)

Either an unsigned integer or a UUID string. Nothing else. Omit it and the platform generates a UUID for you. Upserting a point with an existing id overwrites that point — that's the "up" in upsert.

Invalid ids are rejected:

{"error":"point 0: id must be an unsigned integer or a UUID string","request_id":"..."}
{"error":"a string id must be a UUID (or use an unsigned integer)","request_id":"..."}

Payload (optional)

Arbitrary JSON metadata stored with the point. Payloads are what make search useful in practice: at query time you can filter to points whose payload matches a condition (see Search). Store whatever you'll want to filter on or display — tags, source URLs, timestamps, the original text a vector was made from.

Write limits

  • At most 1000 points per upsert request (at most 1000 points per request (got N)), and at least one (points must contain at least one point).
  • Batches are all-or-nothing: one bad point rejects the whole request; nothing is written.
  • Any request body is capped at 32 MiB.

Summary checklist

DecisionRule of thumb
NameLowercase, digits, hyphens; ≤ 48 chars; pick something you can grep for
DimensionsCopy your embedding model's output size; you cannot change it later
Distancecosine unless your model's docs say otherwise; you cannot change it later
IdsLet the platform generate UUIDs unless you need to overwrite points deterministically
PayloadStore everything you'll filter on or need to show in results
Advanced optionsLeave at defaults until memory cost forces the question

Next: Search covers how to query all of this.