> For the complete documentation index, see [llms.txt](https://docs.umh.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.umh.app/production/sizing-guide.md).

# Sizing Guide

## Supported Architectures

| Architecture | Status            | Notes                                                                             |
| ------------ | ----------------- | --------------------------------------------------------------------------------- |
| x86\_64      | ✅ Fully supported | Intel/AMD 64-bit processors                                                       |
| ARM64        | ✅ Fully supported | 64-bit ARM processors (AWS Graviton, Apple Silicon, etc.)                         |
| Raspberry Pi | ❌ Not supported   | Redpanda requires 48-bit virtual address space; Raspberry Pi provides only 38-bit |

**Why Raspberry Pi doesn't work:** Redpanda uses the Seastar framework which requires a 48-bit virtual address space. Raspberry Pi's ARM processors only provide 38-bit VA space, causing SIGABRT on startup. This is a fundamental hardware limitation documented in [Redpanda GitHub Issue #1542](https://github.com/redpanda-data/redpanda/issues/1542).

## Recommended Starting Point

**Start with → 2 vCPU · 4 GB RAM · 40 GB SSD**

#### What that box handles

* **≈ 4 bridges instances** (e.g. OPC UA ➜ Redpanda) **plus one bridge instance** that forwards from the local Redpanda to an external MQTT broker
* **≈ 900 tags at 1 message / second each**
* Keeps **seven days** of replayable raw history under the defaults a new instance starts with (`log_retention_ms = 7 days`, `log_cleanup_policy = delete`)
* Leaves enough CPU headroom that [CPU Health](/usage/instances/cpu-health.md) stays healthy, so new bridges can still start

#### Disk usage in practice

Redpanda writes **128 MiB segments**; a segment can be deleted only after it is closed.\
With Snappy compression, a typical 200 B JSON payload shrinks to ≈ 50–70 B (3–4× ratio).\
Allowing a 5 GB safety buffer, a 40 GB SSD gives **≈ 35 GB usable history ≙ \~500–700 million messages**.

Size the disk against your message rate, not your tag count: seven days of raw history is what makes replay possible, and time-based retention has no size ceiling of its own. At 700 messages / second — ≈ 423 million records over seven days — `umh.messages` alone needs roughly **40–55 GB**. Measure the real figure on your instance, since payload size drives it.

*Need more?*\
Shorten retention (either during install with `internal.redpanda.redpandaServiceConfig.topic.defaultTopicRetentionMs` or later on the topic level using `rpk`), cap the topic with `defaultTopicRetentionBytes`, or enlarge the disk. A byte cap protects the disk but can cut the replay window below seven days under heavy load.

#### Memory

| Component           | Rule of thumb                                    |
| ------------------- | ------------------------------------------------ |
| Redpanda            | ≈ 2 GB · cores + 1.5 GB head-room (Seastar rule) |
| Agent + supervision | ≈ 150 MB                                         |
| Each extra pipeline | ≈ 100 MB                                         |

#### CPU

**Theoretical Bridge Limits:**

* We recommend **5 bridges per CPU core** (after reserving 1 core for Redpanda)
* Example: 2 CPU cores = (2-1) × 5 = **5 bridges maximum**
* Example: 4 CPU cores = (4-1) × 5 = **15 bridges maximum**

**Dynamic Resource Protection:** Since every bridge has different resource requirements (OPC UA with 10,000 tags uses more CPU than MQTT with 100 tags), we also monitor actual resource usage:

* **CPU Utilization**: With the [CPU health check](/usage/instances/cpu-health.md), which is on by default, usage alone does not make a new bridge wait. The check uses 70% usage only as a last-resort fallback, when no CPU limit is set, the kernel publishes no PSI, and the machine's free cores cannot be measured. If UMH Core cannot read a file it needs to measure the CPU, CPU health is degraded and a new bridge waits. Under the 70% CPU usage rule (`USE_FSMV2_CPU=false`), a new bridge waits while the whole machine's CPU usage is at 70% or more
* **CPU Throttling**: A new bridge waits while the container is being throttled. Throttling means the system needs brief CPU bursts (e.g., when processing message batches) but hits the CPU limit, causing delays and degraded performance even if average CPU usage looks acceptable
* **Memory Usage**: A new bridge waits while memory use is above 80%
* **Disk Usage**: A new bridge waits while disk use is above 85%

**Redpanda CPU Utilization:** UMH Core runs Redpanda with the `--overprovisioned` flag, which optimizes CPU usage for containerized environments. This disables Seastar's busy-polling reactor model, reducing idle CPU usage from 100% to near-zero when not processing messages. The trade-off is slightly higher latency (microseconds to low milliseconds), which is acceptable for manufacturing data that doesn't require sub-millisecond response times. This is required because UMH Core runs in Docker where CPU pinning doesn't work effectively, and Redpanda shares the container with other processes.

**Automatic Enforcement:** The system will prevent you from deploying new bridges if:

1. You've reached the theoretical limit for your CPU allocation, OR
2. The system detects resource degradation (high CPU, throttling, memory, or disk pressure), OR
3. The instance's resource health is not proven yet, for example right after a restart

This check is bridge admission. The emergency setting *Turn off bridge admission* turns it off, in your `config.yaml`:

```yaml
agent:
  enableResourceLimitBlocking: false  # Start bridges even when a resource is degraded or not proven yet, or the bridge limit is reached
```

`true` is the default, also when `config.yaml` does not contain the key. While it is `false`, the instance shows as degraded. See [Bridges Do Not Start](/usage/data-flows/bridges/bridges-do-not-start.md) for the full procedure.

While bridge admission is on, it keeps one bridge from overloading the others. If you need more bridges, either:

* Increase CPU allocation (for containerized deployments)
* Upgrade to a larger instance (for VM/bare-metal deployments)
* Optimize existing bridges (reduce polling rates, tag counts, or processing complexity)

#### Resource Limit Error Messages

When a new bridge waits, its status reason says why:

* **Bridge limit**: `Cannot create bridge - limit exceeded (5 bridges maximum with 2.0 CPU cores, 1 core reserved for Redpanda)`
* **High CPU**: `CPU degraded: CPU utilization critical`
* **High Memory**: `Memory degraded: Memory usage at 85%`
* **High Disk**: `Disk degraded: Disk usage at 90%`
* **Health not proven yet**: `Resource health not proven yet`

#### Easy vertical scaling

UMH Core is stateless besides the **`/data`** volume. To grow:

1. Stop the container
2. Move or resize the volume / attach it to a bigger VM
3. Start the same image — no reinstall or re-configuration required

#### High availability

For multi-node failover, mount `/data` on storage accessible from multiple nodes. See [High Availability](/production/high-availability.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.umh.app/production/sizing-guide.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
