Prometheus & Grafana Requirements — Per Target Growth Model
Version 1.6.9 | Updated: August 08, 2026
Prometheus & Grafana Requirements — Per Target Growth Model
How to size the stack when adding servers and exporters.
Every number below is measured, on a named environment, on a stated date. Where a figure is an extrapolation rather than a measurement, it says so — the distinction matters, because the two deployments we run differ by more than 2× in total series and by 8× on individual exporters.
Versions this describes: Prometheus v3.13.1, Grafana 12.3.0, both pinned
in prometheus-grafana-stack/.env.example, which is the runtime truth.
1. The two reference deployments
Measured 05.08.2026.
On-prem (grafrd) — VMs and Compose, ~10 monitored hosts:
-
38 targets, 86.6k active series
-
Prometheus: 0.8 GB resident, 28.9 GB on disk, 10.7k samples/s
-
Retention 90 days, and the TSDB holds a full 90.1 days — so the disk figure is a steady state, not a database still filling up
-
Host: 12 vCPU, 62 GB RAM, 436 GB disk
Kubernetes (ocp-frdly, namespace acs) — 3 nodes:
-
36 targets, 220.6k active series
-
Prometheus: 1.2 GB resident, 6.9k samples/s
Scrape interval is 10s globally, with 5s on two jobs and 30s on several
others (prometheus.yml). Earlier guidance in this file said 60s, which
understates ingestion — and therefore disk — by about six times.
2. Series per target — measured, both environments
count by (job) ({name=~".+"}) divided by that job’s target count.
A dash means the job does not exist in that environment.
| Exporter / Job | Kubernetes | On-prem | Notes |
|---|---|---|---|
kube-state-metrics |
~26.3k |
— |
Cluster object inventory; scales with objects, not nodes |
cAdvisor |
~20.7k |
~0.78k |
Per-container. Dominates in Kubernetes, a rounding error on VMs — it scales with pods per node |
MySQL Exporter |
~18.2k |
~27.7k |
The largest single exporter on-prem. Grows with tables and |
JmxExporter |
~10.6k |
~2.6k |
Hazelcast + WildFly MBeans. Fixed set per member |
process-exporter |
~8.4k |
~2.6k |
Grows with matched process groups |
node-exporter |
~7.2k |
~3.2k |
Varies with filesystem and interface count |
Longhorn |
~2.8k |
— |
Only where Longhorn is the storage provider |
ClickHouse |
~1.9k |
~0.82k |
Native endpoint |
Prometheus (self) |
~1.3k |
~1.6k |
|
PostgreSQL |
~0.77k |
~0.70k |
|
Alertmanager |
~0.54k |
~0.48k |
|
Northbound API |
~0.53k |
~1.5k |
|
Provision API |
~0.48k |
~0.41k |
|
FTACS / acs-metrics |
~0.48k |
~0.19k |
|
ft-system-metrics |
~0.46k |
~0.76k |
|
UI Backend |
~0.39k |
~0.65k |
|
Service API |
~0.38k |
~0.32k |
|
FT Device Network |
~0.15k |
~0.18k |
|
AI Agent |
~0.06k |
~0.09k |
|
Nginx |
~0.06k |
~0.06k |
|
kubelet |
~0.01k |
— |
Three things to take from this.
Size for the infrastructure exporters, not the applications. In Kubernetes, kube-state-metrics plus cAdvisor, process-exporter and node-exporter are 64% of the total; add MySQL and Longhorn and it is 77%. On-prem, MySQL alone is a third. Meanwhile all nine application and API jobs together come to ~4.2k in Kubernetes and ~4.3k on-prem — under 2% either way.
The same exporter is not the same size in both. JmxExporter reports 4× more per target in Kubernetes, process-exporter 3× more, node-exporter 2× more — different hosts, different process lists, different filesystems. Use the column that matches where you are deploying.
These are orders of magnitude, not constants. A node exporter on a host with many filesystems reports considerably more than one with few.
Re-measure rather than trusting this table when it matters:
# on-prem
curl -sG --data-urlencode 'query=count by (job) ({__name__=~".+"})' \
http://localhost:9090/api/v1/query
# Kubernetes
kubectl -n <ns> exec deploy/ft-prometheus -- \
wget -qO- 'http://localhost:9090/api/v1/query?query=count+by+(job)+({__name__=~".%2B"})'
3. Storage
Derived from the on-prem measurement — 86.6k series, 10s scrape, a full 90 days on disk:
~0.33 GB per 1k active series.
Retention and scrape interval both move that linearly: halving the interval doubles it, and so does doubling retention. At the default 90 days and 10s:
| Active series | Disk at 90d / 10s |
|---|---|
100k |
~33 GB |
250k |
~83 GB |
500k |
~165 GB |
1M |
~330 GB |
2M |
~660 GB |
Leave headroom above these. Compaction needs room to write a new block before dropping the old one, and a full disk stops ingestion rather than slowing it.
4. Growth calculation
-
List the exporters the new node will run.
-
Take the series-per-target values from §2, from the right column. If a database exporter or cAdvisor is among them, expect it to dominate.
-
Sum them and add to the current total (
prometheus_tsdb_head_series). -
Check §5 for CPU and memory, §3 for disk.
5. Scaling thresholds
-
<2M active series → 4 vCPU / 16 GB is sufficient.
-
2—4M → 8 vCPU / 32 GB, SSD 1 TB.
-
4—8M → 16 vCPU / 64—96 GB, SSD 2—4 TB.
-
>8M → 32 vCPU / 96—124 GB, SSD 4—8 TB.
Rules of thumb, not measurements: the largest deployment measured here is 220k series, so every row but the first is extrapolation. What the measurements do support is that the first row is not tight — at 220k series Prometheus holds 1.2 GB resident, so 16 GB has a great deal of room before memory is the limit.
Grafana load is driven by users and dashboards rather than by series count.
6. Examples
A monitored host with a database, on-prem: node-exporter ~3.2k
process-exporter ~2.6k + cAdvisor ~0.8k + MySQL ~27.7k = ~34k series, four
fifths of it the database exporter. About 11 GB of disk at 90d/10s. The same
host without a database is ~7k, about 2 GB.
A Kubernetes worker node: cAdvisor ~20.7k + process-exporter ~8.4k
node-exporter ~7.2k = ~36k series before a single application pod, plus
~0.1—2k for each pod scheduled on it. About 12 GB of disk. Note that
kube-state-metrics (~26k) is per cluster, not per node — it is paid once.
Both stay far inside the <2M baseline.
branch 1.6.9 · commit a862b45d92590285f229f80a6b5d2efabcb3b1b0 · page generated August 08, 2026