Home / AI & GenAI / Vector Databases

AI & GenAIHow-toIntermediate

Standalone Qdrant in production: install, collections, memory, security and snapshots

Run a single-node Qdrant vector database properly. Covers Docker setup with persistent storage, API keys and TLS, collection design with HNSW and quantisation, payload indexes for filters, memory sizing, snapshots and monitoring.

Deepak Bhardwaj3 min read

Applies toQdrant 1.x on Linux (Docker or binary)

1. Run it

docker run -d --name qdrant --restart unless-stopped \
  -p 127.0.0.1:6333:6333 -p 127.0.0.1:6334:6334 \
  -v /srv/qdrant/storage:/qdrant/storage \
  -v /srv/qdrant/snapshots:/qdrant/snapshots \
  -v /srv/qdrant/config.yaml:/qdrant/config/production.yaml \
  -v /srv/qdrant/tls:/qdrant/tls:ro \
  -e QDRANT__SERVICE__API_KEY="$QDRANT_API_KEY" \
  -e QDRANT__SERVICE__READ_ONLY_API_KEY="$QDRANT_RO_KEY" \
  qdrant/qdrant:v1.13.0

Pin a version, and keep storage on a fast SSD volume. The API keys come from environment variables so they stay out of the config file.

# config.yaml
service:
  enable_tls: true
tls:
  cert: /qdrant/tls/cert.pem
  key: /qdrant/tls/key.pem
storage:
  storage_path: /qdrant/storage
  snapshots_path: /qdrant/snapshots

Never expose Qdrant without an API key. Open instances get found and emptied.

2. Create a collection

curl -X PUT "https://qdrant01:6333/collections/kb_docs" \
  -H "api-key: $QDRANT_API_KEY" -H "Content-Type: application/json" -d '{
  "vectors": { "size": 1536, "distance": "Cosine", "on_disk": true },
  "hnsw_config": { "m": 16, "ef_construct": 200 },
  "quantization_config": { "scalar": { "type": "int8", "quantile": 0.99, "always_ram": true } },
  "optimizers_config": { "default_segment_number": 4 }
}'
  • size must match your embedding model (1536 for text-embedding-3-small, 3072 for -large, and so on).
  • Scalar quantisation with always_ram keeps compact int8 vectors in memory and the originals on disk, for about 4× less RAM with a small recall cost (use rescoring to recover most of it).

3. Payload indexes for filters

curl -X PUT "https://qdrant01:6333/collections/kb_docs/index" -H "api-key: $QDRANT_API_KEY" \
  -H "Content-Type: application/json" -d '{"field_name": "tenant_id", "field_schema": "keyword"}'

Index every field you filter on (tenant, document type, ACL group, date). Filters on unindexed fields slow searches down a lot.

4. Memory sizing (rough)

RAM ≈ vectors × dimensions × bytes per value × 1.5 (overhead)
1M × 1536 × 4 bytes (float32) × 1.5 ≈ 9.2 GB
with int8 quantisation in RAM and originals on disk ≈ 2.3 GB + page cache

5. Search with rescoring

POST /collections/kb_docs/points/query
{
  "query": [0.01, 0.02, ...],
  "filter": { "must": [ { "key": "tenant_id", "match": { "value": "acme" } } ] },
  "params": { "hnsw_ef": 128, "quantization": { "rescore": true, "oversampling": 2.0 } },
  "limit": 10,
  "with_payload": true
}

6. Snapshots (backups)

curl -X POST "https://qdrant01:6333/collections/kb_docs/snapshots" -H "api-key: $QDRANT_API_KEY"
curl "https://qdrant01:6333/collections/kb_docs/snapshots" -H "api-key: $QDRANT_API_KEY"

Copy snapshot files from /srv/qdrant/snapshots to object storage on a schedule. To restore: PUT /collections/kb_docs/snapshots/recover with the snapshot location.

7. Monitoring

  • /metrics (Prometheus): request latency, collection sizes, and errors.
  • /collections/kb_docs: status should be green. yellow means optimising, red means an error.
  • Alert on disk usage, memory, and p95 search latency.

8. Limits of standalone

One node means downtime for restarts and upgrades, and no replication. Add a cluster with replication factor ≥ 2 when search is on a critical path (see the vector database HA post).

Tip

Keep the source documents and chunk text in your own store as well. You can always rebuild a vector index from source; you can't rebuild source from the index.