Skip to content

baselhusam/qdrant_exporter

Repository files navigation

Qdrant Exporter

Grafana dashboard screenshot

A Prometheus exporter for self-hosted Qdrant that surfaces per-collection, per-shard, cluster health, and search performance metrics — data that Qdrant's native /metrics endpoint does not expose.

Ships with a pre-built Grafana dashboard. One docker compose up command gives you the full observability stack.


Why this exists

Qdrant's native /metrics endpoint covers Go runtime stats and basic request counts. The rich per-collection data lives in the /telemetry and /cluster JSON endpoints but is never formatted as Prometheus metrics for self-hosted deployments. The detailed exporter (qdrant-cluster-exporter) and /sys_metrics endpoint are cloud-only.

This exporter closes that gap for everyone running Qdrant on bare metal, Docker, or any non-cloud environment.

What you want to know Native /metrics This exporter
Vectors per collection
Shard status per collection
Optimizer state (live)
Search latency by type
Indexing completeness ratio
RAM / disk per collection
Shard transfer progress
Raft consensus health

Quick start

Option A — Pre-built image (recommended)

The exporter is published to two registries — pick whichever is closer to your infrastructure:

Registry Image
Docker Hub baselhusam/qdrant-exporter
GHCR ghcr.io/baselhusam/qdrant-exporter

Both are built and pushed simultaneously on every release. All examples below use the Docker Hub image name — substitute ghcr.io/baselhusam/qdrant-exporter to pull from GHCR instead.

Exporter only

Point it at your Qdrant and expose the metrics port. Prometheus scrapes :9153/metrics.

# Docker Hub
docker run -d \
  --name qdrant-exporter \
  -p 9153:9153 \
  -e QDRANT_EXPORTER_QDRANT__NODES='[{"url":"http://host.docker.internal:6333"}]' \
  --add-host host.docker.internal:host-gateway \
  baselhusam/qdrant-exporter

# GHCR
docker run -d \
  --name qdrant-exporter \
  -p 9153:9153 \
  -e QDRANT_EXPORTER_QDRANT__NODES='[{"url":"http://host.docker.internal:6333"}]' \
  --add-host host.docker.internal:host-gateway \
  ghcr.io/baselhusam/qdrant-exporter

Replace host.docker.internal:6333 with your Qdrant address if it is not on the same host. If Qdrant requires an API key, add "api_key":"your-key" inside the JSON object.

Exporter + Prometheus (no Grafana)

# docker-compose.yml
services:
  qdrant-exporter:
    image: baselhusam/qdrant-exporter
    container_name: qdrant-exporter
    restart: unless-stopped
    ports:
      - "9153:9153"
    environment:
      QDRANT_EXPORTER_QDRANT__NODES: '[{"url":"http://host.docker.internal:6333"}]'
    extra_hosts:
      - "host.docker.internal:host-gateway"

  prometheus:
    image: prom/prometheus:latest
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./deploy/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    extra_hosts:
      - "host.docker.internal:host-gateway"
docker compose up -d

Exporter + Prometheus + Grafana

# docker-compose.yml
services:
  qdrant-exporter:
    image: baselhusam/qdrant-exporter
    container_name: qdrant-exporter
    restart: unless-stopped
    ports:
      - "9153:9153"
    environment:
      QDRANT_EXPORTER_QDRANT__NODES: '[{"url":"http://host.docker.internal:6333"}]'
    extra_hosts:
      - "host.docker.internal:host-gateway"

  prometheus:
    image: prom/prometheus:latest
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./deploy/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    extra_hosts:
      - "host.docker.internal:host-gateway"

  grafana:
    image: grafana/grafana:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: admin
      GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /etc/grafana/provisioning/dashboards/qdrant-overview.json
    volumes:
      - ./deploy/grafana/provisioning:/etc/grafana/provisioning:ro
      - ./dashboards:/etc/grafana/provisioning/dashboards:ro
    depends_on:
      - prometheus
docker compose up -d

Open Grafana at http://localhost:3000 (admin / admin). The dashboard is auto-provisioned.

Full stack — Qdrant + exporter + Prometheus + Grafana

# docker-compose.yml
services:
  qdrant:
    image: qdrant/qdrant:v1.16.3
    restart: unless-stopped
    ports:
      - "6333:6333"
      - "6334:6334"

  qdrant-exporter:
    image: baselhusam/qdrant-exporter
    container_name: qdrant-exporter
    restart: unless-stopped
    ports:
      - "9153:9153"
    environment:
      QDRANT_EXPORTER_QDRANT__NODES: '[{"url":"http://qdrant:6333"}]'
    depends_on:
      - qdrant

  prometheus:
    image: prom/prometheus:latest
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./deploy/prometheus.yml:/etc/prometheus/prometheus.yml:ro

  grafana:
    image: grafana/grafana:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: admin
      GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /etc/grafana/provisioning/dashboards/qdrant-overview.json
    volumes:
      - ./deploy/grafana/provisioning:/etc/grafana/provisioning:ro
      - ./dashboards:/etc/grafana/provisioning/dashboards:ro
    depends_on:
      - prometheus
docker compose up -d

Option B — Docker Compose (clone-based)

If you want the bundled prometheus.yml and Grafana provisioning files without writing them yourself, clone the repo and use the pre-built profiles:

git clone https://github.com/baselhusam/qdrant_exporter
cd qdrant_exporter

# Attach to an existing Qdrant on localhost:6333
docker compose --profile monitoring up -d

# Or spin up the full stack including Qdrant
docker compose --profile fullstack up -d

Open Grafana at http://localhost:3000 (admin / admin). The dashboard is auto-provisioned.

Option C — run the exporter locally (no Docker)

pip install qdrant-exporter

# point it at your Qdrant
qdrant-exporter --config qdrant-exporter.yaml

Then scrape http://localhost:9153/metrics from your existing Prometheus.


Endpoints

Service URL Notes
Grafana http://localhost:3000 admin / admin
Prometheus http://localhost:9090
Exporter http://localhost:9153/metrics Prometheus scrape target
Qdrant http://localhost:6333 fullstack mode only

Architecture

┌─────────────┐     HTTP :6333      ┌──────────────────┐
│   Qdrant    │ ◄────────────────── │ qdrant-exporter  │
│             │   /telemetry        │                  │
│             │   /cluster          └────────┬─────────┘
│             │   /collections               │ :9153/metrics
└─────────────┘                             │
                                   ┌────────▼─────────┐
                                   │    Prometheus    │  scrapes every 15s
                                   └────────┬─────────┘
                                            │ PromQL
                                   ┌────────▼─────────┐
                                   │     Grafana      │
                                   └──────────────────┘

The exporter is pull-based — it queries Qdrant on every Prometheus scrape, not on a timer.


Metrics reference

All metrics are prefixed with qdrant_exporter_.

Collections

Metric Labels Description
collection_vectors_total collection Total vectors
collection_indexed_vectors_total collection Indexed vectors
collection_points_total collection Total points
collection_segments_total collection Segment count
collection_status collection, status 1 = active state (green/yellow/red/grey)
collection_optimizer_status collection, status 1 = active state (ok/error)
shard_vectors_total collection, shard_id Vectors per shard
shard_points_total collection, shard_id Points per shard
shard_vectors_bytes collection, shard_id Vector storage size
shard_payloads_bytes collection, shard_id Payload storage size
shard_state collection, shard_id, state 1 = active state

Cluster

Metric Labels Description
cluster_enabled 1 = distributed mode, 0 = single node
cluster_peers_total Number of nodes in the cluster
cluster_raft_term Current Raft election term
cluster_raft_commit Last committed log index
cluster_raft_pending_operations Ops not yet applied (should be ~0)
cluster_is_leader 1 = this node is the Raft leader
collection_shard_count collection Total shards across all peers
collection_local_shard_points collection, shard_id Points in each local shard
collection_local_shard_state collection, shard_id, state Local shard state
collection_remote_shard_state collection, shard_id, peer_id, state Remote replica state
collection_shard_transfers_active collection Ongoing shard migrations
collection_resharding_operations_active collection Active resharding ops

Performance

Metric Labels Description
search_count_total collection, search_type Searches per index path type
search_fail_count_total collection, search_type Failed searches
search_avg_duration_micros collection, search_type Average search latency (µs)
optimizer_runs_total collection Completed optimization passes
optimizer_runs_failed_total collection Failed optimization passes
optimizer_avg_duration_micros collection Avg optimizer pass duration (µs)
optimizer_active_total collection Currently running optimizer tasks
collection_indexed_ratio collection Indexed vectors / total (0–1)
collection_deleted_vectors_total collection Tombstoned vectors pending compaction
collection_ram_bytes collection RAM used by all segments
collection_disk_bytes collection Disk used by all segments

search_type is one of: unfiltered_hnsw, unfiltered_plain, unfiltered_sparse, unfiltered_exact, filtered_plain, filtered_small_cardinality, filtered_large_cardinality, filtered_exact, filtered_sparse.


Configuration

# qdrant-exporter.yaml
qdrant:
  nodes:
    - url: http://localhost:6333
      api_key: your-key-here     # omit if no auth configured
  scrape_interval: 15            # seconds
  telemetry_details_level: 3     # required for per-collection shard stats on Qdrant 1.16+

exporter:
  port: 9153
  log_level: info                # debug | info | warning | error
  metric_prefix: qdrant_exporter

All fields can be overridden with environment variables using the QDRANT_EXPORTER_ prefix and __ as the nested delimiter:

QDRANT_EXPORTER_QDRANT__NODES='[{"url":"http://localhost:6333","api_key":"secret"}]'
QDRANT_EXPORTER_EXPORTER__PORT=9153
QDRANT_EXPORTER_EXPORTER__LOG_LEVEL=debug

Telemetry (details_level) on Qdrant 1.16+

Per-collection shard and storage metrics come from GET /telemetry?details_level=N. The legacy style details=level=3 often returns only number_of_collections, so nested collections.collections[] is missing and many qdrant_exporter_* series never appear. The exporter defaults to telemetry_details_level: 3; override via QDRANT_EXPORTER_QDRANT__TELEMETRY_DETAILS_LEVEL if needed.

Scraping native Qdrant /metrics

The bundled Grafana Overview row includes panels that use native qdrant_* series from Qdrant’s own HTTP /metrics (for example high-level process stats). Configure Prometheus to scrape both Qdrant (:6333/metrics) and this exporter (:9153/metrics); see deploy/prometheus.yml for a sample.


Grafana dashboard

Grafana Dashboards

The dashboard (dashboards/qdrant-overview.json) is auto-provisioned when using the Docker Compose setup. It has four rows:

  • Overview — total collections, vectors, points, Qdrant version, cluster mode, memory, per-collection health tiles
  • Search Performance — search rate (req/s) via deriv() on cumulative-style gauges, avg latency by search type (ms), error rate, search count by type
  • Storage & Indexing — indexing ratio gauge (alerts below 1.0), RAM and disk per collection, optimizer run history, deleted vectors
  • Cluster — cluster mode, Raft leader status, pending operations, peer count, shard transfer tracking

You can also import it directly from Grafana.com → or manually from dashboards/qdrant-overview.json.

Dashboard screenshot 2

Dashboard screenshot 3


Version compatibility

Tested against Qdrant v1.13.0 – v1.17.1. The exporter performs a version check at startup and prints a compatibility assessment.

The minimum version where core telemetry fields are present is approximately v1.7.0. Older versions will work but some metrics may return 0.


License

Apache 2.0

About

Prometheus exporter for self-hosted Qdrant — surfaces per-collection, shard, and cluster metrics that the native `/metrics` endpoint doesn't expose

Topics

Resources

License

Stars

6 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors