NEW

Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

Elasticsearch Heap Size Setting

The Elasticsearch heap is the JVM-managed memory used for query coordination, aggregations, cluster state, indexing buffers, and various caches. Correctly sizing the heap is one of the highest-leverage tuning decisions for an Elasticsearch cluster - undersized heaps trip circuit breakers and trigger OOMs, while oversized heaps cause long garbage collection pauses and waste memory that Lucene's file-system cache would use more productively.

  • Rule 1: Set -Xms and -Xmx to the same value to disable heap resizing
  • Rule 2: Heap should be at most 50% of physical RAM. The other 50% is for Lucene memory-mapped files via the OS page cache
  • Rule 3: Stay under ~30-31 GB to keep compressed ordinary object pointers (compressed oops). Above that threshold, the JVM switches to 64-bit pointers and effective memory drops sharply
  • Modern versions (7.11+): Auto-sized based on available RAM if no override is set

Modern Heap Configuration (7.x and later)

If no -Xms/-Xmx is configured, Elasticsearch sets the heap automatically based on node role and available RAM. For most workloads the auto-sizing is acceptable for prototyping but should be reviewed before production.

To override, do not edit config/jvm.options directly - add a custom file under config/jvm.options.d/:

-Xms16g
-Xmx16g

JVM options files must use the .options suffix and are processed in lexicographic order. Per-install-method paths:

Install type Custom JVM options path
tar.gz / zip config/jvm.options.d/
deb / rpm /etc/elasticsearch/jvm.options.d/
Docker bind-mount into /usr/share/elasticsearch/config/jvm.options.d/

The ES_JAVA_OPTS environment variable also works but is harder to audit:

export ES_JAVA_OPTS="-Xms16g -Xmx16g"

Sizing Guidelines

Physical RAM Recommended heap Notes
8 GB 4 GB Min viable for non-trivial workloads
16 GB 8 GB Common dev/test node
32 GB 16 GB Typical production data node
64 GB 30 GB Sweet spot - max compressed oops
128 GB 30 GB + larger Lucene cache Don't exceed 30 GB heap
256 GB+ Run multiple Elasticsearch instances per host with 30 GB heap each

Above ~30 GB heap, compressed oops disable and the addressable heap drops to roughly 28-32 GB of usable memory until ~50 GB. Anywhere between is wasted - either stay under 30 or commit to ~50+ GB and accept the overhead.

The 30 GB Compressed Oops Threshold

The JVM uses compressed 32-bit object pointers when heap is below a platform-specific threshold (typically 30-32 GB). Above that, pointers grow to 64 bits, increasing memory consumption per object by roughly 25%. The exact crossover depends on the JVM version - check with:

java -Xmx31g -XX:+PrintFlagsFinal -version | grep UseCompressedOops

For Elasticsearch, sticking to -Xmx30g (or -Xmx29g for safety) is the standard production recommendation.

Legacy Heap Configuration (6.x and earlier)

Older versions used ES_HEAP_SIZE:

export ES_HEAP_SIZE=8g

Or by directly editing jvm.options. Modern installations should not use ES_HEAP_SIZE; the variable is deprecated.

Common Pitfalls

  1. Setting -Xmx greater than 50% of RAM. Lucene relies heavily on the OS page cache for fast term dictionary and doc value lookups - starving the cache slows queries dramatically.
  2. Setting -Xms smaller than -Xmx. The JVM will resize the heap dynamically, causing GC pause spikes and wasted memory commit/release.
  3. Crossing the 30 GB threshold. The heap looks bigger but addressable memory drops due to disabled compressed oops.
  4. Setting heap based on data volume. Heap size correlates with concurrent query and aggregation load, not stored data. A 1 TB cold-tier node may run fine on 8 GB heap; a 200 GB hot tier under heavy aggregation may need 30 GB.

Monitoring Heap Health

Useful APIs:

GET /_nodes/stats/jvm?filter_path=nodes.*.jvm.mem
GET /_nodes/stats/jvm?filter_path=nodes.*.jvm.gc

Watch:

  • Heap used after GC (should stabilize well below max)
  • Young-gen GC frequency and duration
  • Old-gen GC count - frequent old GCs are a heap-pressure red flag
  • Circuit breaker trips (parent breaker, fielddata, request)

Prevent Heap Misconfiguration with Pulse

Pulse is an AI DBA for Elasticsearch and OpenSearch that tracks -Xms, -Xmx, GC duration, and circuit-breaker activity across every node, flagging:

  • Drift between intended and actual heap sizing (a common pattern after auto-sizing kicks in on 7.11+ when a node moves to a host with different RAM)
  • Settings that are unsafe for your workload: heap above 31 GB triggers loss of compressed oops; heap above 50% of physical RAM starves Lucene's page cache; -Xms not equal to -Xmx causes resize-driven GC spikes
  • The downstream operational impact: old-gen GC frequency, parent/fielddata/request breaker trips, OOM patterns

When a node's working set outgrows its heap, or a config change accidentally puts heap into the wasted 30-50 GB compressed-oops dead zone, Pulse names the misconfiguration with the supporting GC and breaker evidence already collected.

Connect your cluster.

Frequently Asked Questions

Q: How much heap should I give Elasticsearch?
A: At most 50% of physical RAM, and no more than approximately 30 GB to preserve compressed ordinary object pointers. For most production data nodes, 16-30 GB of heap on a 32-64 GB machine is the sweet spot.

Q: Why shouldn't Elasticsearch heap exceed 30 GB?
A: Above roughly 30-31 GB the JVM disables compressed oops, switching from 32-bit to 64-bit object pointers. The addressable heap drops by ~25% until the heap grows past ~50 GB, so any value between is strictly worse than 30 GB.

Q: Should -Xms and -Xmx be the same?
A: Yes. Setting them equal pre-allocates the full heap and disables runtime resizing, which avoids GC pauses and memory churn. Elasticsearch's bootstrap check warns when they differ in production mode.

Q: How do I change the Elasticsearch heap size?
A: Add a file under config/jvm.options.d/ (e.g. heap.options) containing -Xms16g and -Xmx16g. Do not edit jvm.options directly. Restart the node for the change to apply.

Q: Does Elasticsearch auto-configure heap size?
A: Yes, since 7.11 Elasticsearch auto-sizes the heap based on RAM and node roles if no explicit -Xmx/-Xms is provided. Review the chosen value before production - auto-sizing is sensible but rarely optimal for known workloads.

Q: What happens if Elasticsearch heap is too small?
A: Symptoms include frequent old-gen GCs, circuit breaker trips, OOM errors, slow aggregations, and node instability. The fix is to raise heap (within the 30 GB / 50% guardrails) or scale out.

Q: What's the best tool to prevent Elasticsearch heap misconfiguration?
A: Pulse is purpose-built for this. It is an AI DBA for Elasticsearch and OpenSearch that tracks -Xms/-Xmx, GC duration, and circuit-breaker activity on every node, flags heap above the 31 GB compressed-oops threshold or above 50% of RAM, and recommends sizing changes with the GC and OOM evidence already attached.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.