Collection declarations make vector topology reviewable alongside the queries that use it. Define vectors first, add payload indexes for fields you filter or order by, and add shard keys only when Qdrant routing is part of the design.
Model the vector topology
Section titled “Model the vector topology”Vector names are application-defined. dense, sparse, and colbert are useful conventions, but vector configuration determines the actual role. A dense definition is name VECTOR(size, distance) with distance COSINE, DOT, EUCLID, or MANHATTAN; a sparse definition is name SPARSE with optional WITH SPARSE (...) / WITH INDEX (...) config. Dense vectors may also set a storage datatype (float32, float16, uint8, or turbo4 for TurboQuant 4-bit) and a memory placement.
CREATE COLLECTION research ( dense VECTOR(384, COSINE), colbert VECTOR(128, COSINE) WITH HNSW (m = 0) WITH MULTIVECTOR (comparator = 'max_sim'), sparse SPARSE)WITH HNSW (m = 16, ef_construct = 100);| Requirement | Schema choice |
|---|---|
| Semantic retrieval | A dense VECTOR(size, distance) |
| Lexical or sparse retrieval | A named SPARSE vector |
| Late interaction | A multivector with a comparator |
| Hybrid retrieval | Both a dense and sparse vector |
Collection modes
Section titled “Collection modes”A CREATE COLLECTION can name a mode instead of (or alongside) explicit vector definitions. Modes infer a conventional topology:
| Mode | Resulting topology |
|---|---|
| (no mode) | Bare dense topology without a model hint |
USING DENSE MODEL 'name' | Dense topology with dimension inference from the model |
USING HYBRID | Conventional hybrid dense + sparse topology |
HYBRID RERANK | Conventional rerank topology |
HYBRID DENSE VECTOR semantic_v2 SPARSE VECTOR lexical_v2 | Hybrid topology with arbitrary role names |
Explicit dense and sparse vector definitions may coexist with the collection blocks below. Dense size must be positive.
Collection configuration blocks
Section titled “Collection configuration blocks”Config blocks attach to the collection with WITH <BLOCK> (...) and to individual dense vectors (WITH HNSW, WITH VECTOR, WITH QUANTIZATION, WITH MULTIVECTOR). Keys are ASCII case-insensitive and unique.
| Block | Accepted keys |
|---|---|
HNSW | m, ef_construct, full_scan_threshold, max_indexing_threads, on_disk, payload_m, inline_storage, memory (cold/cached/pinned) |
VECTOR | on_disk, memory (cold/cached/pinned), datatype (float32/float16/uint8/turbo4) |
OPTIMIZERS | deleted_threshold, vacuum_min_vector_number, default_segment_number, max_segment_size, memmap_threshold, indexing_threshold, flush_interval_sec, max_optimization_threads, prevent_unoptimized |
PARAMS | replication_factor, write_consistency_factor, on_disk_payload, payload_memory (cold/cached only), shard_number, sharding_method, shard_keys, read_fan_out_factor, read_fan_out_delay_ms |
QUANTIZATION | type (scalar/binary/product/turbo), disabled, always_ram, quantile, bits, compression, encoding, query_encoding, memory |
WAL | wal_capacity_mb, wal_segments_ahead, wal_retain_closed (create only) |
STRICT_MODE | enabled, max_query_limit, max_timeout, search_allow_exact, search_max_oversampling, and the remaining StrictModeConfig keys |
METADATA | Free-form string keys with any JSON value |
MULTIVECTOR | comparator (max_sim) |
sparse INDEX/SPARSE | modifier, full_scan_threshold, on_disk, datatype (float32/float16/uint8; not turbo4), memory |
read_fan_out_factor and read_fan_out_delay_ms parse on CREATE and ALTER: create-time values apply with a follow-up PATCH, since the create wire shape carries no fan-out fields. QUANTIZATION (disabled = true) is an ALTER form. WITH WAL is create-only. ALTER COLLECTION applies any of the HNSW, VECTOR, OPTIMIZERS, PARAMS, QUANTIZATION, STRICT_MODE, or METADATA blocks to an existing collection.
Alter one vector
Section titled “Alter one vector”ALTER also accepts per-vector diffs. The named dense form is WITH VECTOR <name> (<nested blocks>) with HNSW (...), QUANTIZATION (...), or VECTOR (...) blocks — comma-separated, each at most once. The unnamed WITH VECTOR (...) form targets the default unnamed vector. Sparse vectors use WITH SPARSE <name> (SPARSE (...) | INDEX (...)). Every block is field-wise: unset keys keep their current value. datatype has no per-vector diff field on the Qdrant wire and is rejected (QQL-PARSE-VECTOR-DIFF); duplicate vector names, duplicate nested blocks, and empty blocks are rejected too. Diff names are validated against the collection schema before the update is sent (QQL-UNKNOWN-VECTOR when the vector does not exist).
ALTER COLLECTION docs WITH VECTOR dense ( HNSW (m = 32, memory = 'cold'), QUANTIZATION (type = 'scalar', quantile = 0.99), VECTOR (memory = 'cached', on_disk = true) );
ALTER COLLECTION docs WITH VECTOR colbert (QUANTIZATION (disabled = true));
ALTER COLLECTION docs WITH SPARSE bm25 (SPARSE (modifier = 'idf', full_scan_threshold = 5000, datatype = 'float16'));Memory placement (Qdrant 1.19+)
Section titled “Memory placement (Qdrant 1.19+)”memory controls how a component is held in RAM while data remains on disk: cold (load on demand), cached (OS page cache), or pinned (keep resident). payload_memory is the payload counterpart under WITH PARAMS and accepts only cold or cached — pinned is rejected for payload. Prefer memory / payload_memory for new scripts; legacy on_disk / on_disk_payload / always_ram still parse and dual-write through 1.19.
CREATE COLLECTION docs ( dense VECTOR(384, COSINE) WITH VECTOR (memory = 'cached', datatype = 'turbo4'))WITH HNSW (memory = 'cold')WITH PARAMS (payload_memory = 'cold');
CREATE COLLECTION docs2 ( sparse SPARSE WITH SPARSE (modifier = 'idf', memory = 'cached'));
CREATE COLLECTION docs3 ( dense VECTOR(128, DOT) WITH QUANTIZATION (type = 'scalar', memory = 'pinned'));CREATE COLLECTION sec10k ( dense VECTOR(768, COSINE), sparse SPARSE)WITH HNSW (m = 16, ef_construct = 100)WITH PARAMS (replication_factor = 2, shard_number = 8, sharding_method = 'custom', shard_keys = ['honeywell', 'ge']);
ALTER COLLECTION sec10k WITH QUANTIZATION (type = 'scalar');CREATE COLLECTION docs (v VECTOR(8, COSINE)) WITH WAL (wal_capacity_mb = 32, wal_segments_ahead = 2, wal_retain_closed = 1);
CREATE COLLECTION docs (v VECTOR(8, COSINE)) WITH STRICT_MODE (enabled = true, max_query_limit = 100);
CREATE COLLECTION docs (v VECTOR(8, COSINE)) WITH METADATA (owner = 'team', version = 3);
ALTER COLLECTION docs WITH STRICT_MODE (enabled = false);
ALTER COLLECTION docs WITH METADATA (owner = 'team');Index the filter paths you use
Section titled “Index the filter paths you use”Create payload indexes for fields used frequently in filters, tenant predicates, or ordering. Index design is a Qdrant performance decision, not a requirement for every payload field. The index TYPE is keyword, integer, float, geo, text, bool, datetime, or uuid.
CREATE INDEX ON COLLECTION research FOR tenant_id TYPE keyword WITH (is_tenant = true, on_disk = true);
CREATE INDEX ON COLLECTION research FOR title TYPE keyword WITH (prefix = true, memory = 'cached');
CREATE INDEX ON COLLECTION research FOR content TYPE text WITH (tokenizer = 'multilingual', lowercase = true, phrase_matching = true);
CREATE INDEX ON COLLECTION research FOR body TYPE text WITH (stopwords = 'english');
CREATE INDEX ON COLLECTION research FOR body TYPE text WITH (stopwords = {languages: ['english'], custom: ['foo']});CREATE INDEX ... WITH (...) accepts the following options:
| Option | Type |
|---|---|
is_tenant, on_disk, enable_hnsw | boolean |
lowercase, ascii_folding, phrase_matching, lookup, range, is_principal, prefix | boolean |
min_token_len, max_token_len | non-negative integer |
tokenizer | string |
stemmer | string |
stopwords | string list, bare language name, or {languages, custom} set |
memory | 'cold', 'cached', or 'pinned' |
A bare language (stopwords = 'english') plans to the languages set. Unknown languages fail at plan; unknown set keys fail at parse.
prefix = true enables keyword prefix matching for WHERE field MATCH PREFIX (Qdrant 1.19+). DROP INDEX ON COLLECTION research FOR field removes an index.
Inspect resources with SHOW
Section titled “Inspect resources with SHOW”There is no SHOW INDEXES. The supported forms are:
| Statement | Returns |
|---|---|
SHOW COLLECTIONS; | All collection names |
SHOW COLLECTION name; | A single collection's configuration |
SHOW SHARD KEYS ON COLLECTION name; | The custom shard keys of a collection |
SHOW QUOTAS; | Cluster-wide resource quota config and utilization (REST only) |
Manage cluster quotas (REST only)
Section titled “Manage cluster quotas (REST only)”SHOW QUOTAS and SET QUOTA (...) map to Qdrant's GET|PUT /quotas REST API. They are not available over gRPC (QQL-GRPC-QUOTA) or the edge backend (QQL-EDGE-UNSUPPORTED-QUOTA).
SET QUOTA is a full replace: PUT /quotas replaces the whole configuration. Omitted keys (including an explicit key = null) are unset in the replacement body — they do not merge with previous limits. Optional WAIT true|false waits for consensus after the update.
SHOW QUOTAS;
SET QUOTA (enabled = true, max_resident_memory_percent = 80, max_disk_usage_percent = 90, release_margin_percent = 5) WAIT true;
SET QUOTA (enabled = false);
SET QUOTA (max_disk_usage_percent = null);Invalid quota keys or out-of-range percentages fail planning with QQL-PLAN-QUOTA.
Route a collection with custom shard keys
Section titled “Route a collection with custom shard keys”Shard-key DDL creates and manages routing partitions. It is separate from the tenant predicate your service must enforce.
CREATE SHARD KEY 'acme' ON COLLECTION research WITH (shards_number = 2);
CREATE SHARD KEY 'acme' ON COLLECTION research WITH (shards_number = 2, placement = [1, 2], initial_state = 'Active');
SHOW SHARD KEYS ON COLLECTION research;
DROP SHARD KEY 'acme' ON COLLECTION research;placement is a peer-id list. initial_state is a replica-state string.
Next: Data operations and Multitenancy.