Several official Elasticsearch documents recommend not assigning more than 32 GB of heap to a single instance. But memory is relatively cheap now, and limiting a physical server to a single 32 GB Elasticsearch node can feel wasteful. One practical way to use the hardware better is to run multiple Elasticsearch instances on the same server.
This post summarizes the key points for running two Elasticsearch instances on one machine. The same idea can be extended to even more instances.
Why stay under 32 GB?
The Elasticsearch documentation has long warned users not to cross the 32 GB heap boundary, for example in the well-known article Don’t Cross 32 GB!.
Because of that recommendation, running multiple instances on one host can sometimes make better use of a large-memory server.
Configuration changes
To run multiple instances on a single host, the default configuration needs a few adjustments.
node.max_local_storage_nodes
This setting limits how many local storage nodes can run on the same machine. Since we want multiple instances, it should be set to 2 or higher.
http.port
This is the HTTP port Elasticsearch exposes to clients. By default, Elasticsearch will try ports in the 9200 to 9299 range. If 9200 is in use, it will move to 9201 automatically.
Technically you do not have to set this manually, but for clearer configuration management and easier compatibility with older setups, it is better to assign fixed ports. For example:
- instance 1:
9200 - instance 2:
9201
transport.tcp.port
This is the port used for inter-node cluster communication. By default it starts from 9300, and just like the HTTP port, Elasticsearch will move to the next available port if needed.
Again, fixed values are easier to manage:
- instance 1:
9300 - instance 2:
9301
discovery.zen.ping.unicast.hosts
From Elasticsearch 2.x onward, the old multicast discovery mode is gone, so you need to specify master discovery targets explicitly.
This is especially important when running multiple instances on one host. If an instance uses transport.tcp.port: 9301 and you only specify a hostname without a port in discovery.zen.ping.unicast.hosts, the node may assume the peer is also on 9301, which can prevent it from discovering the master correctly.
So include the master’s transport port explicitly:
1 | discovery.zen.ping.unicast.hosts: ["testes.mydomain:9300"] |
Other settings
node.name: two instances on the same host must have different node namespath.data: each instance needs its own data directorypath.logs: separate log directories are strongly recommended
Example configurations
Instance 1
1 | cluster.name: testes |
Instance 2
1 | cluster.name: testes |
Deploying the configs
By default, Elasticsearch reads config/elasticsearch.yml and config/logging.yml from the installation directory.
To start two instances separately, create two subdirectories such as:
1 | config/instance1 |
Each directory should contain its own elasticsearch.yml and logging.yml.
The main config file must still be named elasticsearch.yml, so separate directories are the easiest approach.
Starting the instances
Instance 1
1 | bin/elasticsearch -Des.path.conf=config/instance1 -d -p /tmp/elasticsearch_1.pid |
Instance 2
1 | bin/elasticsearch -Des.path.conf=config/instance2 -d -p /tmp/elasticsearch_2.pid |