﻿---
title: JVM settings
description: If needed, you can override the default JVM options by adding custom options files (preferred) or setting the ES_JAVA_OPTS environment variable. JVM...
url: https://www.elastic.co/elastic/docs-builder/docs/2948/reference/elasticsearch/jvm-settings
products:
  - Elasticsearch
applies_to:
  - Elastic Stack: Generally available
---

# JVM settings
If needed, you can override the default JVM options by adding custom options files (preferred) or setting the `ES_JAVA_OPTS` environment variable.
JVM options files must have the suffix *.options* and contain a line-delimited list of JVM arguments. JVM processes options files in lexicographic order.
Where you put the JVM options files depends on the type of installation:
- tar.gz or .zip: Add custom JVM options files to `config/jvm.options.d/`.
- Debian or RPM: Add custom JVM options files to `/etc/elasticsearch/jvm.options.d/`.
- Docker: Bind mount custom JVM options files into `/usr/share/elasticsearch/config/jvm.options.d/`.

<warning>
  Setting your own JVM options is generally not recommended and could negatively impact performance and stability. Using the Elasticsearch-provided defaults is recommended in most circumstances.
</warning>

<note>
  Do not modify the root `jvm.options` file. Use files in `jvm.options.d/` instead.
</note>


## JVM options syntax

A JVM options file contains a line-delimited list of JVM arguments. Arguments are preceded by a dash (`-`). To apply the setting to specific versions, prepend the version or a range of versions followed by a colon.
- Apply a setting to all versions:
  ```text
  -Xmx2g
  ```
- Apply a setting to a specific version:
  ```text
  17:-Xmx2g
  ```
- Apply a setting to a range of versions:
  ```text
  17-18:-Xmx2g
  ```
  To apply a setting to a specific version and any later versions, omit the upper bound of the range. For example, this setting applies to Java 17 and later:
  ```text
  17-:-Xmx2g
  ```

Blank lines are ignored. Lines beginning with `#` are treated as comments and ignored. Lines that aren’t commented out and aren’t recognized as valid JVM arguments are rejected and Elasticsearch will fail to start.

## Use environment variables to set JVM options

In production, use JVM options files to override the default settings. In testing and development environments, you can also set JVM options through the `ES_JAVA_OPTS` environment variable.
```sh
export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djava.io.tmpdir=/path/to/temp/dir"
./bin/elasticsearch
```

If you’re using the RPM or Debian packages, you can specify `ES_JAVA_OPTS` in the [system configuration file](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/setting-system-settings#sysconfig).
<note>
  Elasticsearch ignores the `JAVA_TOOL_OPTIONS` and `JAVA_OPTS` environment variables.
</note>


## Set the JVM heap size

By default, Elasticsearch automatically sets the JVM heap size based on a node’s [roles](/elastic/docs-builder/docs/2948/reference/elasticsearch/configuration-reference/node-settings#node-roles) and total memory. Using the default sizing is recommended for most production environments.
To override the default heap size, set the minimum and maximum heap size settings, `Xms` and `Xmx`. The minimum and maximum values must be the same.
The heap size should be based on the available RAM:
- Set `Xms` and `Xmx` to no more than 50% of the total memory available to each Elasticsearch node. Elasticsearch requires memory for purposes other than the JVM heap. For example, Elasticsearch uses off-heap buffers for efficient network communication and relies on the operating system’s filesystem cache for efficient access to files. The JVM itself also requires some memory. It’s normal for Elasticsearch to use more memory than the limit configured with the `Xmx` setting.
  <note>
  When running in a container, such as [Docker](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-docker), the total memory available to Elasticsearch means the amount of memory available within the container, not the total system memory on the host.If you are running multiple Elasticsearch nodes on the same host, or in the same container, the total of all the nodes' heap sizes should not exceed 50% of the total available memory.Account for the memory usage of other processes running on the same host, or in the same container, when computing the total memory available to Elasticsearch.The 50% guideline is intended as a safe upper bound on the heap size. You may find that heap sizes smaller than this maximum offer better performance, for instance by allowing your operating system to use a larger filesystem cache.If you set the heap size too large, Elasticsearch may perform poorly and nodes may be terminated by the operating system.
  </note>
- Set `Xms` and `Xmx` to no more than the threshold for compressed ordinary object pointers (oops). The exact threshold varies but 26GB is safe on most systems and can be as large as 30GB on some systems. To verify you are under the threshold, check the Elasticsearch log for an entry like this:
  ```txt
  heap size [1.9gb], compressed ordinary object pointers [true]
  ```
  Or check the `jvm.using_compressed_ordinary_object_pointers` value for the nodes using the [nodes info API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-nodes-info):
  ```json
  ```

The more heap available to Elasticsearch, the more memory it can use for its internal caches. This leaves less memory for the operating system to use for the filesystem cache. Larger heaps can also cause longer garbage collection pauses.
To configure the heap size, add the `Xms` and `Xmx` JVM arguments to a custom JVM options file with the extension `.options` and store it in the `jvm.options.d/` directory. For example, to set the maximum heap size to 2GB, set both `Xms` and `Xmx` to `2g`:
```txt
-Xms2g
-Xmx2g
```

For testing, you can also set the heap sizes using the `ES_JAVA_OPTS` environment variable:
```sh
ES_JAVA_OPTS="-Xms2g -Xmx2g" ./bin/elasticsearch
```

The `ES_JAVA_OPTS` variable overrides all other JVM options. We do not recommend using `ES_JAVA_OPTS` in production.
<note>
  If you are running Elasticsearch as a Windows service, you can change the heap size using the service manager. See [Install and run Elasticsearch as a service on Windows](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-zip-on-windows#windows-service).
</note>


## JVM heap dump path setting

Depending on your stack version, Elasticsearch configures the JVM to dump the heap on out of memory exceptions to the following location by default:
- <applies-to>Elastic Stack: Generally available since 9.1</applies-to> The default logs directory
- <applies-to>Elastic Stack: Generally available in 9.0</applies-to> The default data directory

Directory location:
<tab-set>
  <tab-item title="Logs directory">
    - [RPM](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-rpm) and [Debian](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-debian-package) packages: `/var/log/elasticsearch`
    - [Linux and MacOS](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-from-archive-on-linux-macos) and [Windows](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-zip-on-windows) distributions: The `logs` directory at the root of the Elasticsearch installation
  </tab-item>

  <tab-item title="Data directory">
    - [RPM](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-rpm) and [Debian](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-debian-package) packages: `/var/lib/elasticsearch`
    - [Linux and MacOS](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-from-archive-on-linux-macos) and [Windows](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-zip-on-windows) distributions: The `data` directory at the root of the Elasticsearch installation
  </tab-item>
</tab-set>

If this path is not suitable for receiving heap dumps, modify or add the `-XX:HeapDumpPath=...` entry in [`jvm.options`](#set-jvm-options):
- If you specify a directory, the JVM will generate a filename for the heap dump based on the PID of the running instance.
- If you specify a fixed filename instead of a directory, the file must not exist when the JVM needs to perform a heap dump on an out of memory exception. Otherwise, the heap dump will fail.


## GC logging settings

By default, Elasticsearch enables garbage collection (GC) logs. These are configured in [`jvm.options`](#set-jvm-options) and output to the same default location as the Elasticsearch logs. The default configuration rotates the logs every 64 MB and can consume up to 2 GB of disk space.
You can reconfigure JVM logging using the command line options described in [JEP 158: Unified JVM Logging](https://openjdk.java.net/jeps/158). Unless you change the default `jvm.options` file directly, the Elasticsearch default configuration is applied in addition to your own settings. To disable the default configuration, first disable logging by supplying the `-Xlog:disable` option, then supply your own command line options. This disables *all* JVM logging, so be sure to review the available options and enable everything that you require.
To see further options not contained in the original JEP, see [Enable Logging with the JVM Unified Logging Framework](https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html#enable-logging-with-the-jvm-unified-logging-framework).

### Examples

Change the default GC log output location to `/opt/my-app/gc.log` by creating `$ES_HOME/config/jvm.options.d/gc.options` with some sample options:
```shell
# Turn off all previous logging configurations
-Xlog:disable

# Default settings from JEP 158, but with `utctime` instead of `uptime` to match the next line
-Xlog:all=warning:stderr:utctime,level,tags

# Enable GC logging to a custom location with a variety of options
-Xlog:gc*,gc+age=trace,safepoint:file=/opt/my-app/gc.log:utctime,level,pid,tags:filecount=32,filesize=64m
```

Configure an Elasticsearch [Docker container](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-docker) to send GC debug logs to standard error (`stderr`). This lets the container orchestrator handle the output. If using the `ES_JAVA_OPTS` environment variable, specify:
```sh
MY_OPTS="-Xlog:disable -Xlog:all=warning:stderr:utctime,level,tags -Xlog:gc=debug:stderr:utctime"
docker run -e ES_JAVA_OPTS="$MY_OPTS"
```


## JVM fatal error log setting

By default, Elasticsearch configures the JVM to write fatal error logs to the default logging directory. On [RPM](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-rpm) and [Debian](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-debian-package) packages, this directory is `/var/log/elasticsearch`. On [Linux and MacOS](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-from-archive-on-linux-macos) and [Windows](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/2948/deploy-manage/deploy/self-managed/install-elasticsearch-with-zip-on-windows) distributions, the `logs` directory is located under the root of the Elasticsearch installation.
These are logs produced by the JVM when it encounters a fatal error, such as a segmentation fault. If this path is not suitable for receiving logs, modify the `-XX:ErrorFile=...` entry in [`jvm.options`](#set-jvm-options).

## DNS cache settings

Elasticsearch runs with a security manager in place. With a security manager in place, the JVM defaults to caching positive hostname resolutions indefinitely and defaults to caching negative hostname resolutions for ten seconds.
Elasticsearch overrides this behavior with default values to cache positive lookups for sixty seconds, and to cache negative lookups for ten seconds. These values should be suitable for most environments, including environments where DNS resolutions vary with time.
If these default values are not suitable, you can edit them:
- Cache positive lookups: `es.networkaddress.cache.ttl`
- Cache negative lookups: `es.networkaddress.cache.negative.ttl`

The values [`networkaddress.cache.ttl=<timeout>`](https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.md) and [`networkaddress.cache.negative.ttl=<timeout>`](https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.md) in the [Java security policy](https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.md) are ignored by Elasticsearch unless you remove the settings for `es.networkaddress.cache.ttl` and `es.networkaddress.cache.negative.ttl`.