skip to content

In Qdrant, what do VectorParams size and distance fix at collection creation?

level: middleimportance: must knowfreq 78%

answer

  1. declared once, never changed
  2. dimension plus metric
  3. wrong length is rejected, not padded
  4. new model means a new collection
  5. cosine is normalized at insert

basics

~20 s

VectorParams pins a Qdrant collection's vector dimension and its distance metric for the collection's lifetime. Every upserted point must match that size exactly, and neither value can be changed later — switching embedding models means creating a new collection.

solid answer

~40 s

You create a collection with `client.create_collection(collection_name="docs", vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE))`. `size` is the dimensionality every vector in that collection must have; `distance` is one of `Distance.COSINE`, `Distance.DOT`, `Distance.EUCLID` or `Distance.MANHATTAN`. Both are structural: they are baked into the storage and index layout, so there is no update call that changes them. Upserting a vector of the wrong length fails the whole request with a dimension error rather than padding or truncating. One detail worth knowing: for `Distance.COSINE` Qdrant normalizes vectors as they are stored, so scoring is a dot product at query time — cosine costs no more than dot at search, but the stored vectors are not the raw ones you sent. Because size drives memory (roughly 4 bytes per dimension per vector, plus the index), it is also your main capacity lever.

code

python · 15 lines
python
from qdrant_client import QdrantClient, models

client = QdrantClient(url="http://localhost:6333")

if not client.collection_exists("docs"):
    client.create_collection(
        collection_name="docs",
        vectors_config=models.VectorParams(
            size=1536,
            distance=models.Distance.COSINE,
        ),
    )

info = client.get_collection("docs")
print(info.config.params.vectors.size, info.config.params.vectors.distance)

go deeper

for a junior

Know that a Qdrant collection is created with a fixed vector size and a distance metric, and that the size must match your embedding model's output dimension.

for a middle

Explain that both fields are immutable, that a mismatched vector length fails the request, and that Qdrant normalizes vectors on insert when the metric is cosine.

for a senior

Show you can plan a model change: new collection, re-embed, verify recall, switch behind an alias. Be ready to estimate memory from point count times dimension times four bytes.

for a principal

Own the consequence that vector dimension is a long-lived architectural commitment driving cluster cost and every future migration, and argue for a re-embedding path that can run without downtime before the first collection is created.

## The shape contract A Qdrant collection is a named container whose vector shape is declared once, when you create it. The declaration is a `VectorParams` object: `client.create_collection(collection_name="docs", vectors_config=models.VectorParams(size=1536, distance=models.Distance.COSINE))` Two fields do the work. `size` is the number of dimensions each stored vector must have — it comes straight from the embedding model you plan to use, not from anything Qdrant chooses. `distance` is the similarity function used to compare vectors, chosen from the `Distance` enum: `COSINE`, `DOT`, `EUCLID`, `MANHATTAN`. Everything else about the collection — payload schema, how many points, which fields you filter on — is dynamic. These two are not. ## Why they are immutable Both values are structural inputs to how vectors are laid out on disk and how the similarity graph is built. Changing the metric would invalidate every distance already computed while building the index; changing the dimension would invalidate every stored vector. There is no `update_collection` field that flips either one. The practical consequence is the one interviewers are checking for: **a new embedding model means a new collection.** If you move from a 768-dimension model to a 1536-dimension model, you create a second collection, re-embed and load your corpus into it, and cut traffic over — typically with a collection alias so readers never see the switch. The same is true of a metric change. If you built with `EUCLID` and later decide the model's vectors are meant to be compared by angle, you rebuild. ## What happens on a mismatch Upserting a 512-dimension vector into a `size=768` collection is rejected: the server returns a `Wrong input` error describing the dimension mismatch, and the whole request fails. Qdrant does not zero-pad, does not truncate, and does not accept the point and quietly exclude it from search. This is a feature — silent shape coercion would produce a collection that returns results but scores them meaninglessly. In practice the failure shows up during a bulk load, and the cause is almost always two code paths embedding with different models, or a truncated/pooled embedding that lost dimensions before it reached the client. ## The cosine detail Cosine similarity is the angle between two vectors, which requires dividing by both magnitudes. Doing that per comparison at query time would be wasteful, so Qdrant normalizes vectors to unit length **as they are stored** when the collection's distance is `COSINE`. After normalization, the dot product equals the cosine, so search is a plain dot product. Two consequences follow. First, cosine is not slower than dot product in Qdrant — the cost is paid once at insert. Second, the vector you read back (with `with_vectors=True`) is the normalized one, not the raw embedding you sent. If your application needs the original magnitudes for anything, keep them yourself. Note also that for already-normalized embeddings — which most modern text encoders produce — `COSINE` and `DOT` rank identically; the choice matters when magnitudes carry meaning. ## Picking the metric Match the metric to what the embedding model was trained with. Sentence-embedding models trained with a cosine objective should use `COSINE`. Models whose training objective is an inner product, and recommender-style embeddings where magnitude encodes confidence or popularity, want `DOT`. `EUCLID` suits embeddings in a genuine metric space, such as some image or geospatial feature vectors. Getting this wrong does not raise an error — it silently degrades relevance, which is why it is a favourite interview probe. ## Size as a capacity decision Dimension is also the dominant term in your memory bill. A float32 vector costs about `size * 4` bytes, so ten million 1536-dimension vectors are roughly 60 GB of raw vector data before any index structures. This is why dimension-reduction choices at the model layer, and Qdrant's compression options, are usually discussed together with `size`. When you are sizing a cluster, start from point count times dimension times four and treat that as a floor. ## Companion calls `client.create_collection` fails if the collection already exists, so idempotent setup code pairs it with `client.collection_exists(collection_name)`. `client.get_collection(collection_name)` returns the live configuration plus counters such as `points_count` and the collection `status`, which is the quickest way to confirm in production what shape a collection was actually created with — useful when the deployed config and the code you are reading have drifted.

  • Your embedding provider ships a better model with a different dimension. Walk me through the migration.
    Create a second collection with the new `size`, re-embed the corpus and load it there, and verify recall on a held-out query set. Then point an alias at the new collection so readers switch atomically, keep the old collection around briefly as a rollback, and delete it once you are confident. There is no in-place resize.
  • If my embeddings are already unit length, does choosing COSINE over DOT change anything?
    Not the ranking — for unit vectors the dot product equals the cosine, so results come out in the same order. What changes is that `COSINE` makes Qdrant normalize on insert, which makes the behaviour robust if some vectors are not actually normalized. The scores are then in the -1 to 1 range, which is easier to threshold.
  • How would you find out, at runtime, what distance an existing production collection was created with?
    Call `client.get_collection(name)` and read the returned config: the vector params carry both `size` and `distance`. That is the authoritative answer, versus reading provisioning code that may have drifted from what is actually deployed.

saying these in an interview costs you the question

  • Thinks the distance metric can be changed later with an update call
  • Believes Qdrant pads or truncates vectors to the declared size
  • Claims cosine search is slower than dot product in Qdrant
  • Assumes one collection can hold mixed-dimension vectors
  • Picks a metric arbitrarily instead of matching the embedding model

context