# Resource use compared

Memory, CPU, disk, and install steps of kogut and similar tools, measured with one workload on one machine.

kogut and six alternatives ran side by side on one machine on 16 Oct 2026, each with
50 HTTP checks, except maintenant, whose free edition accepts only 10. The tools do
different work, so read each number with the [limits](#limits) below. Features and
numbers change between versions.

## Results

Memory is the PSS of all of a tool's processes in MiB: the median while idle and the
median with 50 HTTP checks every 60 s, or 10 for maintenant. CPU is seconds used in the
30 minutes with checks.

| Tool | Memory idle | Memory with checks | CPU | Disk after 40 min |
|---|---|---|---|---|
| kogut, server and agent | 17.9 MiB | 19.1 MiB | 13.2 s | 6.5 MB |
| Beszel and Uptime Kuma 2 | 224.5 MiB | 229.5 MiB | 18.2 s | 21.3 MB |
| maintenant | 54.1 MiB | 55.1 MiB, 10 checks | 1.8 s, 10 checks | 5.7 MB |
| Gatus | 30.6 MiB, 1 check | 36.7 MiB | 3.1 s | 4.5 MB |
| Kener and Redis | 204.7 MiB | 225.8 MiB | 19.6 s | 2.8 MB |
| Peekaping | 320.3 MiB | 371.4 MiB | 74.7 s | 5.9 MB |
| Checkmate and MongoDB | 411.2 MiB | 457.9 MiB | 44.9 s | 212 MB |

Most of kogut's CPU time is its agent: 10.9 of 13.2 s. The agent collects host,
container, and systemd unit metrics every 15 s. Beszel's agent collects once a minute
by default and used 1.7 s. The kogut server, running the 50 checks, used 2.3 s.

| Tool | Components | Download | Steps to a panel with checks |
|---|---|---|---|
| kogut | 1 binary, run as server and agent | 11.6 MB binary, 3.6 MB for the agent alone | 1 install command, 1 account, 1 agent command |
| Beszel and Uptime Kuma 2 | Beszel hub and agent, Uptime Kuma on Node.js | 44 MB of binaries and a 1.76 GB image | 2 installs and 2 accounts; add each system and each monitor in a form |
| maintenant | 1 binary | 68 MB binary or 84 MB image | 1 command, no account |
| Gatus | 1 Go process | 51 MB image | A YAML file and 1 command |
| Kener and Redis | Kener on Node.js, Redis | 573 MB and 40 MB images | A Compose file, 2 settings, 1 account, and removal of 2 demo monitors |
| Peekaping | 7 processes in 1 image: 4 Go services, Redis, Caddy, and supervisord | 445 MB image | 1 command, 1 account |
| Checkmate and MongoDB | Checkmate on Node.js, MongoDB | 0.88 GB and 0.95 GB images | A Compose file, a `JWT_SECRET`, 1 account |

### Memory by component

| Tool | RSS with checks | Private anonymous memory | PSS by component |
|---|---|---|---|
| kogut | 23.4 MiB | 8.7 MiB | Server 15.3 MiB, agent 3.8 MiB |
| Beszel and Uptime Kuma 2 | 232.3 MiB | 134.5 MiB | Uptime Kuma 177.2 MiB, hub 35.1 MiB, agent 17.1 MiB |
| maintenant | 55.1 MiB | 16.3 MiB | One process |
| Gatus | 36.7 MiB | 13.2 MiB | One process |
| Kener and Redis | 226.0 MiB | 145.4 MiB | Kener 211.9 MiB, Redis 13.9 MiB |
| Peekaping | 377.1 MiB | 169.4 MiB | One container |
| Checkmate and MongoDB | 458.0 MiB | 299.2 MiB | MongoDB 235.4 MiB, Checkmate 220.9 MiB |

## Versions

| Tool | Version | How it ran |
|---|---|---|
| kogut | Pre-release commit `0409f91` | Static release build with the panel, as a native process |
| Beszel | 0.21.0 | Official hub and agent binaries, as native processes |
| Uptime Kuma | 2.5.6 | Official image, with SQLite |
| maintenant | 1.9.0, Community edition | Official binary, as a native process, with telemetry turned off |
| Gatus | 5.37.0 | Official image, with SQLite storage |
| Kener | 4.1.7, with Redis 7.4.11 | Official images from its Compose file |
| Peekaping | 0.0.46 | Official SQLite bundle image |
| Checkmate | 3.12.0, with MongoDB 8.0.34 | Official images, without the Capture agent |

Tools that publish a binary ran natively. The others ran in containers, as their
installation guides describe.

## Method

The machine was an AMD Ryzen AI Max+ 395 with 32 threads and 27 GB of RAM, on Linux
7.2. Containers ran in rootless Podman 5.8.

- **Workload.** Each tool had its own HTTP server on `127.0.0.1` that answers `200` on 50
  paths and logs every request. After 10 minutes without checks, each tool got 50 HTTP
  `GET` checks every 60 s, one per path, for 30 minutes. The request logs confirm 50
  checks a minute from each tool, and 10 from maintenant. Tools that can collect host
  metrics did so.
- **Setup.** A script created each tool's first account, hosts, and checks through its
  API, configuration file, or setup form, with no manual steps.
- **Grouping.** Each component ran in its own cgroup. A tool's figures add up all of its
  processes, including databases, Redis, supervisord, and Caddy. Container runtime
  processes, such as conmon and pasta, are not counted for any tool.
- **Sampling.** Every 10 s, a sampler added up `Rss`, `Pss`, and `Swap` from
  `/proc/<pid>/smaps_rollup` for each process and read `memory.stat` and `cpu.stat` from
  the cgroup. Idle figures cover the first 10 minutes, including the first start. Loaded
  figures cover the next 30 minutes.
- **CPU and disk.** CPU is the growth of the cgroup's `usage_usec` in the 30 minutes with
  checks. Disk is the size of the data directory or volume after 40 minutes.
- **Swap.** Swap was turned off for the measured cgroups, with no memory limit, so the
  kernel could not move idle pages out of RSS.
- **Repeat.** All seven tools ran at the same time, started a minute apart. A second run
  with swap turned on,
  counting PSS plus swap, agreed within 10% for memory and within 6 to 25% for CPU, with
  the tools in the same order.

## Which memory figure

RSS counts every page a process maps, including the binary and shared libraries, in
full for each process. PSS splits shared pages between the processes that share them, so
adding up a tool's processes does not count them twice. Private anonymous memory, from
`memory.stat`, is the heap and stacks only, without pages mapped from files.

The same tool gives different numbers in each: kogut has 23.4 MiB RSS, 19.1 MiB PSS,
and 8.7 MiB private anonymous memory. maintenant has 55.1 MiB RSS and 16.3 MiB private
anonymous memory, because its large static binary maps much code. A figure published for
a tool may be any of these, so compare the same kind.

`memory.current`, which `docker stats` reports, also counts page cache charged to the
cgroup. It depends on which process first read a file, so it is not compared here.

## Limits

- One machine, one CPU type, and 40 minutes. The results do not show growth over days
  and weeks, and disk after 40 minutes shows the rate of writes, not a steady size.
- Nobody used the panels during the run. kogut's figures for panel use are in
  [What is kogut](https://docs.kogut.dev/introduction/what-is-kogut/#resource-use), measured as RSS with another workload.
- The tools do different work. kogut, Beszel, and maintenant collected host metrics.
  Checkmate ran without its Capture agent, and Gatus, Kener, and Peekaping collect no
  host metrics.
- maintenant's Community edition accepts only 10 checks, so its loaded row is 10 checks.
- Gatus needs at least one endpoint, so it had one check while idle. It has no accounts
  and no editing in its dashboard.
- Kener uses about 500 MiB for its first two minutes after starting, then about 200 MiB.
- The machine was a shared workstation with other work running, not a clean host. This
  affects CPU more than memory.
- Uptime Kuma used SQLite through `UPTIME_KUMA_DB_TYPE=sqlite`, the same choice its setup
  screen offers. Kener's two demo monitors were removed. maintenant's telemetry was turned
  off.
- kogut was a pre-release build, static like the release binaries. A glibc build uses
  3 to 4 MiB more.
