> ## Documentation Index
> Fetch the complete documentation index at: https://www.meilisearch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Prometheus endpoint

> Expose Meilisearch instance metrics in Prometheus format for scraping by Prometheus, Grafana, or any compatible monitoring stack.

Meilisearch can expose internal metrics through a `GET /metrics` endpoint in the [Prometheus text exposition format](https://prometheus.io/docs/instrumenting/exposition_formats/). You can scrape this endpoint with Prometheus, visualize it in Grafana, or feed it into any compatible monitoring stack.

> [!NOTE]
>
> Meilisearch Cloud provides managed [monitoring dashboards](https://www.meilisearch.com/docs/capabilities/platform/monitoring/overview.md) for search performance, operations, and indexing. The Prometheus endpoint is primarily useful for self-hosted instances that integrate with an existing Prometheus and Grafana setup.

> [!WARNING]
>
> The `/metrics` endpoint is an [experimental feature](https://www.meilisearch.com/docs/capabilities/platform/management/experimental_features.md). Metric names, labels, and behavior may change between Meilisearch versions without following semantic versioning. Track its status in the [product discussion](https://github.com/meilisearch/product/discussions/625).

## Enabling the endpoint

The endpoint is disabled by default. Enable it in one of three equivalent ways.

**At launch, with a CLI flag or environment variable:**

```sh CLI flag theme={null}
meilisearch --experimental-enable-metrics
```

```sh Environment variable theme={null}
export MEILI_EXPERIMENTAL_ENABLE_METRICS=true
```

**At runtime, with the experimental features API** (no restart required):

```sh theme={null}
curl -X PATCH "${MEILISEARCH_URL}/experimental-features" \
  -H 'Authorization: Bearer MASTER_KEY' \
  -H 'Content-Type: application/json' \
  --data '{"metrics": true}'
```

The runtime setting is persisted in the database. On startup, the effective value is the CLI flag or environment variable **OR** the persisted value. This means a flag at launch enables the endpoint even if the persisted setting is `false`, and a persisted `true` survives restarts without the flag.

## Authentication

If your instance has a master key configured, requests to `/metrics` must be authenticated:

* Send the master key, or an API key with one of the `metrics.get`, `metrics.*`, or `*` actions, in the `Authorization` header.
* The API key must be authorized on **all indexes** (`"indexes": ["*"]`). A key scoped to specific indexes is rejected with an `invalid_api_key` error.

If no master key is configured, no authentication is required.

```sh theme={null}
curl "${MEILISEARCH_URL}/metrics" \
  -H 'Authorization: Bearer MASTER_KEY'
```

## Response format

A successful request returns `200 OK` with a plain-text body (`text/plain; version=0.0.4`). Each metric is preceded by `# HELP` and `# TYPE` comment lines:

```text theme={null}
# HELP meilisearch_index_docs_count Meilisearch Index Docs Count
# TYPE meilisearch_index_docs_count gauge
meilisearch_index_docs_count{index="movies"} 31944
```

### Errors

| Situation | HTTP | Error code |
| - | - | - |
| Feature not enabled | 400 | `feature_not_enabled` |
| Missing `Authorization` header (when a master key is set) | 401 | `missing_authorization_header` |
| Key lacks the `metrics.get` action or is not scoped to all indexes | 403 | `invalid_api_key` |

## Metrics reference

All metric names are prefixed with `meilisearch_`. Most gauges are computed at scrape time, so their resolution equals your scrape interval.

### Database and index stats

| Metric | Type | Labels | Description |
| - | - | - | - |
| `meilisearch_db_size_bytes` | gauge | None | Total size of the database on disk in bytes, including free space reclaimable by LMDB |
| `meilisearch_used_db_size_bytes` | gauge | None | Portion of the database actually used, in bytes |
| `meilisearch_index_count` | gauge | None | Number of indexes on the instance |
| `meilisearch_index_docs_count` | gauge | `index` | Number of documents per index |
| `meilisearch_last_update` | gauge | None | Unix timestamp of the last update to the instance |
| `meilisearch_is_indexing` | gauge | None | `1` if a task is currently being processed, otherwise `0` |

### Task queue

| Metric | Type | Labels | Description |
| - | - | - | - |
| `meilisearch_nb_tasks` | gauge | `kind`, `value` | Task counts broken down by `kind="statuses"`, `kind="types"`, and `kind="indexes"` |
| `meilisearch_task_queue_latency_seconds` | gauge | None | Age in seconds of the oldest task still enqueued or processing (`0` when the queue is empty) |
| `meilisearch_task_queue_max_size` | gauge | None | Maximum size of the task queue database, in bytes |
| `meilisearch_task_queue_used_size` | gauge | None | Currently used size of the task queue database, in bytes |
| `meilisearch_task_queue_size_until_stop_registering` | gauge | None | Remaining bytes before the queue refuses new tasks |

For `meilisearch_nb_tasks`, the `value` label depends on `kind`: task statuses (enqueued, processing, succeeded, failed, canceled), task types (such as `documentAdditionOrUpdate` or `settingsUpdate`), or index uids.

### Batch and indexing progress

These gauges are recomputed on every scrape and can legitimately be absent from the output when nothing is being processed.

| Metric | Type | Labels | Description |
| - | - | - | - |
| `meilisearch_batch_running_progress_trace` | gauge | `batch_uid`, `step_name` | Completion ratio (0 to 1) of each step of the currently processing batch |
| `meilisearch_last_finished_batches_progress_trace_ms` | gauge | `batch_uid`, `step_name` | Duration in ms of each step of the most recently finished batch. Step names are hierarchical, joined with `>` (for example `processing tasks > indexing`) |
| `meilisearch_last_indexed_documents_count` | gauge | `batch_uid`, `index` | Documents indexed, edited, and deleted by the last succeeded document batch |
| `meilisearch_last_indexed_documents_duration_ms` | gauge | `batch_uid`, `index` | Wall-clock duration in ms of that same batch |

The `last_indexed_documents_*` gauges are useful for computing indexing throughput. They only stay in the output while the batch is "fresh": they disappear once more than the batch duration plus 5 minutes has elapsed. Use a scrape interval of 1 minute or less to reliably capture them.

### HTTP traffic

| Metric | Type | Labels | Description |
| - | - | - | - |
| `meilisearch_http_requests_total` | counter | `method`, `path`, `status` | Total HTTP requests. `path` is the route pattern (for example `/indexes/{index_uid}/search`), not the raw URL |
| `meilisearch_http_response_time_seconds` | histogram | `method`, `path` | Response-time histogram, with buckets from 0.005 to 10 seconds |

`meilisearch_http_requests_total` is counted for every request regardless of whether the metrics feature is enabled. `meilisearch_http_response_time_seconds` is only observed while the feature is enabled, and only for registered routes.

### Search concurrency

| Metric | Type | Labels | Description |
| - | - | - | - |
| `meilisearch_search_queue_size` | gauge | None | Capacity of the search queue (configurable via `--experimental-search-queue-size`, default 1000) |
| `meilisearch_searches_running` | gauge | None | Number of searches currently executing |
| `meilisearch_searches_waiting_to_be_processed` | gauge | None | Number of searches waiting in the queue |

### Feature-specific metrics

| Metric | Type | Labels | Description |
| - | - | - | - |
| `meilisearch_degraded_search_requests` | gauge | None | Number of search requests that were degraded (hit the search cutoff before completing) |
| `meilisearch_personalized_search_requests` | gauge | None | Number of search requests that used personalization |
| `meilisearch_chat_searches_total` | counter | `type` | Searches performed by the chat completions route |
| `meilisearch_chat_prompt_tokens_total` | counter | `workspace`, `model` | LLM prompt tokens consumed by the chat feature |
| `meilisearch_chat_completion_tokens_total` | counter | `workspace`, `model` | LLM completion tokens consumed |
| `meilisearch_chat_tokens_total` | counter | `workspace`, `model` | Total tokens consumed (prompt plus completion) |

## Scraping with Prometheus

Add Meilisearch as a scrape target in your `prometheus.yml`. When a master key is configured, provide an API key with the `metrics.get` action on all indexes:

```yaml theme={null}
scrape_configs:
  - job_name: meilisearch
    scrape_interval: 30s
    static_configs:
      - targets: ['MEILISEARCH_URL']
    authorization:
      type: Bearer
      credentials: 'MEILISEARCH_API_KEY'
```

You can then build dashboards in Grafana on top of these metrics, or configure alerting rules (for example, alerting when `meilisearch_task_queue_size_until_stop_registering` approaches zero).

## Caveats

* **Experimental**: the endpoint, metric names, and labels may change between versions without a deprecation period.
* **Snapshot resolution**: most gauges are computed at scrape time, so their resolution equals your scrape interval.
* **Cardinality**: per-index labels (such as `meilisearch_index_docs_count`) grow with your number of indexes. Instances with thousands of indexes will produce large responses.
* **Freshness window**: the batch-progress and `last_indexed_documents_*` gauges are reset on every scrape and can be absent when nothing is processing or the last batch is too old.

## Next steps

> [card] [Monitoring overview](https://www.meilisearch.com/docs/capabilities/platform/monitoring/overview.md)
>
> Managed monitoring dashboards on Meilisearch Cloud

> [card] [Experimental features](https://www.meilisearch.com/docs/capabilities/platform/management/experimental_features.md)
>
> Enable and manage experimental features

> [card] [Configuration reference](https://www.meilisearch.com/docs/resources/self_hosting/configuration/reference.md)
>
> All CLI options and environment variables


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.