How to monitor Elasticsearch and OpenSearch

Monitor Elasticsearch or OpenSearch through the _cluster/health API: the status must be green, the node count must match what you run, and unassigned shards must be zero. Add disk use against the 85/90/95% watermarks and JVM heap. The health API returns HTTP 200 even when the cluster is red, so assert on the JSON body.

Updated · by PuzariCloud · commands checked against current releases

What can go wrong with Elasticsearch and OpenSearch

  • Red or yellow cluster. Red means at least one primary shard is unassigned: searches return partial results and writes to that index fail. Yellow means replicas are missing, so one more node loss can turn it red.
  • Disk watermarks. At 85% disk used (low watermark) no new shards go to the node, at 90% (high) shards move away, at 95% (flood stage) indices with a shard on that node become read-only and indexing fails with a cluster_block_exception.
  • Heap pressure and circuit breakers. When JVM heap stays above ~85%, garbage collection pauses get long and requests trip circuit breakers (CircuitBreakingException). Nodes that pause too long drop out of the cluster.
  • A node leaves. A node that stops answering is removed; its shards recover elsewhere, which costs I/O and network for minutes or hours.
  • The 200-OK trap. GET _cluster/health answers 200 whether the status is green, yellow or red. An uptime check that only looks at the status code never fires.

The signals that matter, with alert thresholds

SignalAlert whenWhy it matters
statusred: page; yellow for > 15 min: warnData unavailable / no redundancy.
number_of_nodesbelow the number you runA node dropped out.
unassigned_shards> 0 for > 15 minAllocation is stuck, often on disk watermarks.
Highest node disk %≥ 80% warn, ≥ 85% alertStay below the low watermark.
JVM heap used %> 85% sustainedGC pauses and circuit breakers follow.
Search / index latencyp95 doubling vs last weekHot shards, merges or heap trouble.

Thresholds are starting points. Tune them after a week of data: an alert nobody acts on should be raised or removed.

How to check Elasticsearch and OpenSearch by hand

Cluster health
curl -s 'http://localhost:9200/_cluster/health?pretty'
Why is a shard unassigned?
curl -s 'http://localhost:9200/_cluster/allocation/explain?pretty'
Disk per node
curl -s 'http://localhost:9200/_cat/allocation?v'
Heap and disk per node
curl -s 'http://localhost:9200/_cat/nodes?v&h=name,heap.percent,ram.percent,disk.used_percent,node.role'
Unassigned shards and the reason
curl -s 'http://localhost:9200/_cat/shards?v&h=index,shard,prirep,state,unassigned.reason' | grep -v STARTED

With security on (the default since Elasticsearch 8), add -u elastic or -H 'Authorization: ApiKey <key>' and use https. The same APIs work on OpenSearch.

How to watch Elasticsearch and OpenSearch with Vigil

  1. In New monitor pick API check, URL https://es.internal:9200/_cluster/health, header Authorization: ApiKey … (a key with the monitor cluster privilege is enough).
  2. Add assertions, one per line: json status == green, json number_of_nodes >= 3, json unassigned_shards == 0. A failed assertion is confirmed by a second check 12 seconds later and the failure evidence keeps the JSON body.
  3. If the cluster is not reachable from the internet, run the check from a private location: the same agent pulls the job inside your network and Vigil evaluates the result.
  4. On each node, install the server agent and add the disk and heap commands below as custom metrics with limits (es_disk_max_pct = 85, es_heap_max_pct = 85). Add a log_watch for flood stage disk watermark in the cluster log (/var/log/elasticsearch/<cluster.name>.log; one file per entry, no globs).
  5. Add elasticsearch (or opensearch) to the systemd services to watch.
/etc/vigil-agent.json on a node (needs jq)
{
  "commands": {
    "es_disk_max_pct": "curl -s -u monitor:secret 'http://localhost:9200/_cat/allocation?h=disk.percent' | sort -n | tail -1",
    "es_heap_max_pct": "curl -s -u monitor:secret http://localhost:9200/_nodes/stats/jvm | jq '[.nodes[].jvm.mem.heap_used_percent] | max'"
  },
  "log_watch": [
    {"name": "es_flood_stage", "path": "/var/log/elasticsearch/my-cluster.log", "pattern": "flood stage disk watermark"}
  ]
}

Every alert goes to the channels you pick: email, Slack, Telegram, Discord, Microsoft Teams, Pushover, webhooks or on-call paging. Failures are confirmed by a second check before anyone is woken up.

Elasticsearch and OpenSearch monitoring FAQ

Should yellow page someone?

Usually not immediately. A single-node cluster is always yellow if indices have replicas, and a rolling restart is yellow for a while. Alert on red at once and on yellow only when it lasts longer than a normal recovery, e.g. 15 minutes.

How do I unblock an index after the flood stage?

Free disk first. Recent versions remove the index.blocks.read_only_allow_delete block automatically once usage drops below the high watermark; on old versions reset it with a settings update on the index.

Does this work for OpenSearch and Elastic Cloud?

Yes. OpenSearch keeps the same _cluster/health and _cat APIs. For Elastic Cloud, run the API check against the cluster endpoint with an API key.

Vigil by PuzariCloud

Watch Elasticsearch and OpenSearch without stitching five tools together

Uptime and API checks, heartbeats, server and database metrics, traces, errors and logs in one place, with one incident and one alert when something breaks. Every feature is on every plan, including Free.