In this episode we keep Wazuh agile as load grows: tuning the indexer JVM heap, retention policy with index lifecycle, reasonable shard sizes, and the queue and workers on the manager. We also learn to calculate EPS versus resources for 100, 1,000, and 10,000 agents.

In episode 18 we connected Wazuh to TheHive, Shuffle, and notification paths. The more that's sent outward, the greater the load on the manager and indexer. In episode 19 we step back to care for the foundation: how to keep Wazuh responsive as the number of agents and event volume grows.
We'll cover two things that are often mixed up. Performance tuning is action so existing components work efficiently, like adjusting the indexer JVM heap or enlarging the queue. Capacity planning is forward-looking calculation to make sure resources are sufficient, like how much CPU, RAM, and disk for 100, 1,000, or 10,000 agents.
The golden rule is simple: don't add resources before removing waste. Always measure first, then tune, then decide to add hardware. We start with the unit most often used to measure load, events per second, or EPS.
EPS is the number of events entering Wazuh per second. All components, from agent, manager, to indexer, are measured with this unit. You can estimate total EPS with a simple formula:
Total EPS equals the number of agents times the average events per agent per second. One normal agent produces about 1 to 5 EPS depending on the sources monitored. A Windows agent with many event channels tends to be busier than a Linux agent that only reads a few log files.
From this EPS we derive two important needs. First, the compute need to process events on time. Second, the storage need, because every incoming event is stored as a document in the indexer. So before talking about hardware, get used to calculating EPS first.
Info
The average EPS depends heavily on the agent type and logging configuration. Record actual numbers from your deployment over several days, don't just rely on assumptions from documentation pages.
Tuning without data is just guessing. Before changing anything, gather actual numbers from the dashboard and API. A few commands are useful for reading cluster condition:
curl -sk https://localhost:9200/_cat/health?v
curl -sk https://localhost:9200/_cat/indices/wazuh-alerts*?h=index,docs.count,store.sizeFor the manager side, read the state file that records queues and discarded events:
cat /var/ossec/var/run/wazuh-remoted.statePay attention to the discarded_count field. If this number keeps rising, events are starting to be dropped before being processed. That's a sign the queue or workers need tuning, not a sign to immediately add RAM.
The indexer based on OpenSearch runs on Java, and the JVM heap is the key to its performance. A heap that's too small makes garbage collection run too often, while a heap that's too large can leave the operating system short of memory for page cache.
The heap settings are in the indexer's jvm.options file:
-Xms4g
-Xmx4gAs a rule of thumb, set the minimum and maximum equal so Java doesn't keep resizing the heap. A general guideline is around half of the indexer node's total RAM, with a reasonable cap of 4 GB for small deployments and 8 to 16 GB for large ones.
Info
After changing the heap, restart the indexer and monitor its usage. Increase the heap gradually while watching CPU and query latency, not just copying someone else's numbers.
Wazuh alert data grows without stopping, and storage is always the first to give up. Index lifecycle manages the index life cycle: when to rollover, move, and finally delete. Wazuh uses this policy through the Index State Management mechanism on the indexer.
A simple example policy: alert indices stay active for one day, then are deleted after 90 days.
{
"policy": {
"description": "Retensi alert Wazuh selama 90 hari",
"default_state": "hot",
"states": [
{
"name": "hot",
"actions": [
{ "rollover": { "min_index_age": "1d" } }
],
"transitions": [
{ "state_name": "delete" }
]
},
{
"name": "delete",
"actions": [
{ "delete": {} }
]
}
]
}
}Choose the retention period according to compliance needs. Regulations like PCI DSS require certain storage periods, so adjust to the obligations in force, not just how much disk remains. Remember, deleted data can't be recovered unless there's a separate backup.
Each index is divided into shards, and shards that are too small or too numerous are equally troublesome. Too small creates many empty shards that only add overhead. Too large makes recovery and redistribution operations slow.
A general guideline is one shard holding about 5 to 20 GB of data. With daily rollover, the daily index size can be controlled to stay in that range. The actual shard size can be estimated from EPS times rollover duration, then times the average size of one alert.
Don't be tempted to add shards just to look scalable. Notice whether dashboard queries are already slow, then adjust the shard count and indexer node scale.
The manager receives events from thousands of agents via wazuh-remoted, then processes them in wazuh-analysisd. These two points have queues and workers that can be tuned when spikes occur.
<remote>
<connection>secure</connection>
<port>1514</port>
<protocol>tcp</protocol>
<queue_size>196608</queue_size>
</remote>Enlarge the queue only if queues pile up during short spikes. Add workers only to the event categories that are truly the bottleneck. Adding all workers to maximum values instead triggers lots of context switching and can slow everything down.
After tuning, we calculate resources. These numbers are reasonable starting points, not fixed prices:
Disk follows with a simple formula: total EPS times 86,400 seconds times the retention length, then times the average alert size. Because this number can balloon quickly, use that formula to challenge your own retention policy.
In episode 19 you learned how to keep Wazuh agile:
Key takeaways:
In episode 20 we cover the side most often forgotten: monitoring Wazuh itself and setting up proper backup and recovery. See you there!