You add Elasticsearch to a VPS already running nginx, PHP-FPM and MySQL. The initial import of 400,000 product records starts Friday evening. Two hours later the site returns 502: the kernel killed php-fpm — not elasticsearch — because RAM was exhausted and disk cache no longer compensated.
Elasticsearch is not "a MySQL extension". It is a Java engine with I/O and merge spikes competing with your application for the same resources.
Heap, cache and the 50% rule
Elasticsearch uses the JVM for heap (in-memory structures) and relies on the OS filesystem cache for Lucene segments.
| Resource | Role | Common mistake |
|---|---|---|
| JVM heap | Index buffers, queries | Too large → GC pauses, OOM |
| FS cache | Segment reads | Competition with app + OS |
| CPU | Merge, analysis | Saturation during bulk |
| Disk | Merge IOPS + translog | HDD saturated on reindex |
Official Elastic rule: heap ≈ 50% of RAM, max 32 GB. Beyond that, JVM garbage collection loses efficiency.
On a 4–8 GB VPS shared with the app, you are already structurally tight.
Bulk indexing without shaking the machine
1. Throttle throughput
PUT _cluster/settings
{
"persistent": {
"indices.memory.index_buffer_size": "10%"
}
}
Lower refresh_interval to 30s or -1 during mass import, then restore 1s in prod.
2. Batch size — start around 1000–5000 docs, measure latency and rejections.
3. Time window — index overnight if the VPS also serves daytime traffic.
4. Role separation — dedicated ES node or managed offer (Elastic Cloud, OpenSearch managed on your cloud).
Warning signals before OOM
vmstat: ifsi/so(swap) rises during bulk.docker statsorhtop: stable ES heap but total RAM at 100%.- App latency correlated with
_bulkpeaks in ES logs. - Disk > 85% — merge blocked, cluster yellow/red.
Act before kill: pause bulk, add RAM, or migrate ES.
The climax: full-text search does not always justify Elasticsearch
Sizing indexing also means asking whether ES should live on the same machine.
Decide and move forward without blind spots
Calculate RAM budget: Elasticsearch heap plus application plus OS plus 20% headroom. If the app is critical on the same VPS, isolate Elasticsearch on a dedicated node or managed offer before mass import. Route large volumes through a queue with bulk throttle and temporarily raised refresh_interval. Measure vmstat and docker stats during a test import — not only JVM heap. Compare managed Elasticsearch and lighter alternatives (Meilisearch, Typesense) via our compare tool and directory if simple full-text search is enough for the business.
Frequently asked questions
How much RAM for Elasticsearch on an 8 GB VPS?
Heap ≤ 50% RAM, ≤ 32 GB absolute. On shared 8 GB, separating roles is often better.
Why does reindexing crash the server?
Bulk without throttle, intensive merge, cache starved — OOM on app or ES.
Should I index synchronously from the application?
Not for large volumes — queue + bulk workers with tuned refresh_interval.
Is managed Elasticsearch worth the cost?
Yes if indexing is critical and team is small; otherwise Meilisearch or Typesense on budget VPS.
Before indexing overnight, ask: who pays in RAM if bulk goes wrong — Elasticsearch or your live shop?
