Sizing an Elasticsearch cluster node on a KVM VPS requires strictly dividing physical memory between the Java Virtual Machine (JVM) heap and the operating system's filesystem cache. Production best practices dictate allocating exactly 50% of available RAM to the JVM heap, capping it below 31 GB to maintain 32-bit Compressed Ordinary Object Pointers (Compressed OOPs), while leaving the remaining 50% entirely free for Lucene to cache index segments in kernel memory.
The 50% Memory Sizing Rule: Heap vs Filesystem Cache
A common misconception in Elasticsearch administration is that granting the JVM maximum possible RAM improves performance. In reality, Elasticsearch relies heavily on Apache Lucene, which depends directly on the operating system page cache for fast search queries, filter bitsets, and term dictionaries.
When sizing a KVM VPS node:
- Allocate exactly 50% of total RAM to JVM Heap: If your VPS has 16 GB of RAM, assign 8 GB to the JVM heap.
- Reserve 50% for the OS Page Cache: Lucene structures are designed to reside in the Linux kernel buffer cache. Depriving the OS of memory forces Lucene to read index segments from disk, degrading query throughput.
- Keep Min and Max Heap Identical: Set
-Xmsand-Xmxto the exact same value. This prevents the JVM from pausing worker threads during runtime heap expansion or contraction.
Configuring Heap in Modern Elasticsearch
Never edit the root jvm.options file directly, as package upgrades will overwrite custom settings. Instead, create a dedicated configuration file inside the jvm.options.d/ directory:
# /etc/elasticsearch/jvm.options.d/heap.options
-Xms8g
-Xmx8gThe 31 GB Compressed OOPs Threshold
On 64-bit systems, memory pointers consume 8 bytes (64 bits). However, the Java Virtual Machine utilizes a technique called Compressed Ordinary Object Pointers (Compressed OOPs) to represent pointers as 32-bit values, effectively doubling pointer density within CPU cache lines.
Compressed OOPs function only when the heap size remains below approximately 32 GB (often precisely between 30.5 GB and 31.5 GB depending on the specific JDK build). Exceeding this boundary forces the JVM to switch to full 64-bit pointers, consuming up to 40% more memory just to store object references. A node configured with 31 GB of heap frequently has more usable memory than a node with 33 GB or 34 GB. Therefore, never allocate more than 31 GB of heap to a single Elasticsearch instance.
Preventing Swapping and Memory Locking
Swapping memory to disk is fatal for JVM garbage collection performance. When parts of the JVM heap are paged out to swap space, a minor garbage collection cycle can stall for minutes instead of milliseconds, triggering node disconnects and cluster flapping.
To eliminate swapping risks on a Linux VPS:
- Enable Memory Locking: In
/etc/elasticsearch/elasticsearch.yml, setbootstrap.memory_lock: true. - Configure Systemd Limits: Edit the systemd service override via
systemctl edit elasticsearchand addLimitMEMLOCK=infinity. - Adjust Sysctl Swappiness: In
/etc/sysctl.conf, setvm.swappiness = 1to instruct the kernel to swap only under emergency memory conditions.
Disk Allocation Watermarks and Storage Protection
Running out of disk space can corrupt Lucene index files. Elasticsearch incorporates automated disk allocation watermarks that monitor available partition storage and trigger defensive routing actions:
- Low Disk Watermark (Default 85%): Elasticsearch ceases allocating new shards to the node. Existing shards remain writable and continue to accept incoming documents.
- High Disk Watermark (Default 90%): The cluster coordinator actively attempts to relocate existing shards away from this node to other cluster members with lower disk utilization.
- Flood Stage Watermark (Default 95%): A hard safety lock. Elasticsearch enforces a
read_only_allow_deleteblock on every index that has a shard residing on this node. All write operations fail immediately.
Recovering from Flood Stage Lockout
Freeing up disk space by deleting old indices or expanding volume storage does not automatically lift the read-only lock. You must explicitly clear the index block via the Elasticsearch REST API:
curl -X PUT "localhost:9200/*/_settings?pretty" -H 'Content-Type: application/json' -d'
{
"index.blocks.read_only_allow_delete": null
}
'Cluster Node Sizing Matrix
| Workload Tier | Recommended VPS RAM | JVM Heap (-Xms / -Xmx) | Storage Type | Target Shard Volume |
|---|---|---|---|---|
| Development / Small Logs | 8 GB RAM | 4 GB Heap | RAID NVMe (50–100 GB) | Up to 100 GB active data |
| Production Backend Search | 32 GB RAM | 16 GB Heap | RAID NVMe (250–500 GB) | Up to 400 GB active data |
| High-Throughput Analytics | 64 GB RAM | 31 GB Heap (Max Limit) | RAID NVMe (1 TB+) | Up to 800 GB active data |
Deploying Elasticsearch on StreamData KVM VPS
Elasticsearch indexing demands intense random disk I/O alongside sustained memory bandwidth. StreamData KVM VPS plans feature RAID NVMe storage arrays and dedicated compute cores across 10 tiers (1 GB to 128 GB RAM), starting from Rs 149 per month. For high-volume log aggregation or e-commerce search catalogs, high-frequency AMD Ryzen 9 9950X instances provide Zen 5 single-thread execution and DDR5 memory channels.
Browse VPS tiers on StreamData KVM VPS, evaluate enterprise bare-metal on StreamData Dedicated Servers, or explore node connectivity on StreamData Company.