Diagnosing and Fixing JVM Heap Pressure in Elasticsearch Nodes
A practical diagnostic flow for detecting JVM heap pressure in Elasticsearch, with checks, fixes, and escalation steps to restore cluster stability.
28 Jul 2026, 17:11 UTC

Recognizing JVM Heap Pressure in Elasticsearch
When a node repeatedly hits high heap usage (>80%) and the cluster health shifts to yellow or red, the most common culprit is JVM heap pressure. Symptoms include:
- Frequent stop‑the‑world GC pauses in the logs (often >200 ms).
- High
heap.percenton the/_cat/nodesendpoint. - Thread‑pool queues for bulk or search exceeding the configured thresholds.
- Shard reallocation delays and increased node latency.
Below is a concise diagnostic guide that walks you through the checks, fixes, and when to involve Elastic support.
Cause & Diagnostic Table
| Possible Cause | Diagnostic Indicator | Immediate Check |
|---|---|---|
| Heap size too large (>32 GB) causing long GC pauses | Heap.percent > 80% and long GC pause times | Run GET /_cat/nodes?v&h=heap.percent,heap.max,heap.used,heap.avail |
| Fielddata or doc values cache over‑consumption | Cache usage near or above indices.fielddata.cache.size | Check GET /_nodes/stats/jvm and GET /_nodes/stats/indices |
| Thread‑pool back‑pressure from bulk/search requests | Queue lengths > 75% of pool size | Run GET /_nodes/stats/thread_pool |
| Cluster health shifting to yellow/red after GC spikes | Reallocation delays in GET /_cluster/health | Monitor GET /_cluster/health?pretty |
Ordered Checks
- Verify Heap Utilization
GET /_cat/nodes?v&h=heap.percent,heap.max,heap.used,heap.availLook for nodes where
heap.percentexceeds 80%. Note theheap.maxvalue; if it is >32 GB, consider resizing. - Inspect GC Logs
Enable
gc.logor usejcmd VM.logto capture stop‑the‑world events. Search for pauses >200 ms. - Check Thread‑Pool Queues
GET /_nodes/stats/thread_poolIdentify pools (e.g.,
bulk,search) wherequeueis >75% ofsize. High queue lengths indicate back‑pressure. - Assess Cache Usage
GET /_nodes/stats/indicesLook at
indices.fielddata.memory_size_in_bytesandindices.fielddata.evictions. Frequent evictions suggest the cache is too small or the fieldtype is inappropriate. - Cluster Health & Shard Reallocation
GET /_cluster/health?prettyCheck
status,unassigned_shards, anddelayed_unassigned_shards. Long delays correlate with GC activity.
Fixes Tied to Findings
- Resize JVM Heap
Reduce
-Xmxto 1/4 of physical RAM (max 32 GB). For example, changeES_JAVA_OPTSto-Xms16g -Xmx16g. Restart the node after the change. - Adjust Fielddata/Doc Values Cache
If
fielddatausage is high, convert large text fields tokeywordor enabledoc_valueswhere appropriate. Alternatively, increaseindices.fielddata.cache.sizebut only if heap allows. - Tune Thread‑Pool Sizes
Increase
bulkorsearchpool sizes viaES_THREAD_POOL_SIZEorcluster.thread_pool.bulk.size. Monitor queue lengths after each increment. - Reduce Bulk Load Rate
Throttle bulk ingestion by adjusting the producer rate or using
bulk.flush.min_content_size. This reduces bursty GC. - Optimize Mappings
Remove unnecessary
fielddataon text fields, disablenormsif not needed, and usedoc_valuesfor numeric fields. - Enable GC Logging & Tune GC Algorithm
For Java 11+, switch to G1GC with
-XX:+UseG1GCif not already. Verify that pause times drop below 200 ms.
Escalation Criteria
- After applying all fixes, heap.percent remains >80% for more than 30 minutes.
- GC pause times consistently exceed 500 ms despite heap resizing.
- Cluster health stays yellow/red for >15 minutes and shard reallocation stalls.
- Thread‑pool queues stay above 90% of capacity for >10 minutes.
At this point, gather the following and open a support ticket:
- Full JVM heap dump (
jcmd VM.heap_dump). - Recent GC logs (last 24 hours).
- Cluster configuration (
GET /_cluster/settings,GET /_nodes/settings). - Mapping and index settings for affected indices.
Limitations & Practical Verification
The guide assumes Elasticsearch 8.x running on Java 11+. Heap sizing rules change with newer Java versions, so verify the 1/4 rule against your Java documentation. Also, reducing heap may increase GC frequency; monitor gc.log after changes to confirm pause times improve, not just heap usage.
Use Kibana’s Monitoring UI or X-Pack metrics to continuously watch heap.percent, GC pause times, and thread‑pool queues. Set alerts for thresholds that match the escalation criteria.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.