Cluster Sizing
This guide helps you work out how large a Kubernetes cluster you need to run Monad yourself. Read it alongside Installation With Helm and Platform Architecture.
Overview
The Helm chart ships with default resource values, but how much cluster you actually need depends on your workload: how many pipelines you run, what they do, and how much data flows through them. The calculator below estimates that, and the rest of this page explains what goes into it.
Two things to understand up front. First, cost scales with the work your pipelines do — how many there are, how much data flows through them, and how heavy their transforms are. Second, an idle pipeline costs almost nothing — so to stay on the safe side, the calculator sizes as if every pipeline is active at peak. Treat its output as a conservative upper bound.
Interactive calculator
Enter your workload and node size below. The estimate updates as you change the inputs.
Light = field edits / rename / filter. Heavy = jq normalization (e.g. OCSF/ECS) — the main scaling hot spot.
One worker node's size. ~10% CPU / ~12% memory is reserved for the kubelet/system; 110 pods/node cap.
- All pipelines are counted as active — a peak/worst-case estimate. If some of yours sit idle, real usage will be lower; an idle pipeline costs almost nothing.
- Heavy jq is the cost driver — jq normalization costs several times a light transform per record and scales out to multiple replicas. The dominant lever on both CPU and pod count.
- Size for peak — set throughput to your busiest sustained rate, not an average.
- Disk and cluster overhead are not included — NATS JetStream and the metrics store scale with retention × throughput, and your Kubernetes system/observability stack adds its own CPU/RAM. Size those separately.
Each limit separately needs: CPU 6 · memory 1 · pods 3 nodes — the largest sets the minimum. "Recommended" adds ~25% headroom + HA margin. If it's pod-density-bound, raise maxPods rather than using bigger nodes.
| Source | CPU (cores) | Memory (GB) | Pods |
|---|---|---|---|
| Shared control plane | 6.44 | 6.1 | 25 |
| 36 pipelines | 29.78 | 5.8 | 216 |
| Total | 36.2 | 11.9 | 241 |
Model basis & assumptions
Anchored on two real Monad clusters (2026-09): a light/low-throughput deployment and a heavy-jq/high-throughput one. The heavy-jq figure is directly measured; light/none are estimates. All pipelines are treated as active (a peak estimate). This sizes the Monad workload only — add Kubernetes system and observability overhead separately.
- CPU per input record (whole pipeline): light 8.3e-5 · heavy jq 4.7e-4 · none 5e-5 — × rec/s per pipeline.
- Memory: ~0.16 GB / pipeline (≈ flat vs throughput).
- Shared control plane: CPU 2.0 + total rec/s × 7e-5 (NATS is throughput-driven); memory ~6.1 GB; ~25 pods.
- Pods per pipeline: none 2 · light 4 · heavy 6 (incl. replicas). Node usable ≈ 90% CPU / 88% memory; 110 pods/node cap.
Not modelled: disk (needs retention), system/observability overhead, and per-connector variation. Treat as a planning estimate — validate against your own workload before provisioning.
These numbers cover the Monad workload itself — your pipelines plus the components Monad runs (NATS, Postgres, and so on). They don't include your Kubernetes system components or your own observability stack; those are covered in What this does not include.
What goes into the estimate
Four things drive the result:
- Number of pipelines. Each pipeline runs a few pods, so the count sets a floor on how many pods, and therefore nodes, you need — no matter how large the nodes are.
- Transform type. Light transforms (renaming or dropping fields, simple filters) are cheap. Heavy
jqtransforms, such as normalizing to OCSF or ECS, cost several times more per record and are usually the biggest expense in a busy pipeline. - Throughput per pipeline. Records per second at peak. Cost rises roughly in line with this: a pipeline at 5,000 rec/s costs about five times one at 1,000.
- Node size. The vCPU and memory of one worker node. This doesn't change the total resources you need, only how many nodes they spread across. Some of each node is reserved for the kubelet and system, and no node runs more than 110 pods.
Reading the result
The Worker Nodes tile is the headline: the recommended node count for the size you entered, along with the limit that drove it.
That limit, shown as "binds on", is one of three:
- Pod density. You have more pods than the nodes' CPU or memory would otherwise call for, and the 110-pods-per-node cap is what forces more nodes. Bigger nodes won't help; raising
maxPodswill. - CPU. Compute is the bottleneck, usually from busy pipelines running heavy
jqtransforms. - Memory. RAM is the limit. This is rare for Monad.
The Node sizing panel shows the minimum and recommended counts for your node size, and how many nodes CPU, memory, and pods each need on their own — whichever is largest wins. Where it goes splits the totals between Monad's shared components and your pipelines.
Setting values in the chart
Once you have a target, translate it into your values.yaml (the Helm install guide has the full reference):
- Provision the recommended number of nodes at your chosen size.
- If the estimate is pod-density-bound and your CNI allows it, raise
maxPodsper node to fit more pods on each one and bring the count down. - Size the NATS JetStream volume to your retention and throughput rather than leaving the default (see below).
- PostgreSQL storage grows slowly; the default is fine for most deployments.
- If you want the shared components running with multiple replicas for HA, add that overhead to your total.
What this does not include
The calculator covers the Monad workload only. Budget separately for:
- Storage. Disk usage depends on retention and throughput, not pipeline count, so it's sized on its own. The main consumers are the NATS JetStream volume and, if you enable it, the metrics store. Work these out from how long you keep data and how much moves through.
- Kubernetes system components. CNI, DNS, the metrics agent, and similar add-ons take CPU and memory on every node.
- Your observability stack. If you run your own Prometheus or VictoriaMetrics, Grafana, log storage, and so on, that sits on top of the Monad workload and can be sizeable on a busy cluster.
Before you provision
Treat the output as a starting point rather than a final answer. It's built from measurements of real Monad deployments at both light and heavy loads, but your workload will differ. A few habits help:
- Give yourself headroom, then watch real usage once you're running and adjust from there.
- Size for your peak, not a quiet moment.
- Re-run the estimate when your pipeline count, load, or transform complexity changes.
For how these components fit together, see Platform Architecture. For what to watch in production, see Metrics & Monitoring.