Measured on demo-felhom (N100, 16 GB): 61 apps deployed and removed through the product, sampled every 5 s; heavy apps with one real action (Immich 200 photos, Jellyfin transcode, Paperless OCR, Nextcloud 500 MB, ...). sizing.json for the estimator (tools/build_sizing.py), SIZING.md with the proposed minimum machine, METHOD.md. Power is RAPL CPU-package only (no meter). R-993 asks the operator to approve the minimum machine; R-994 lists catalog limits/requests that are too low; R-995 records leftover unnamed volumes after removal. R-231's dated check measured: dooplex-backup.service success, journal green.
12 KiB
What a Felhom box needs — sizing, 2026-10-13
Measured on the N100 demo box (demo-felhom: Intel N100, 4 cores, 16 GB). Method, sources and limits: METHOD.md.
Data file for the future estimator: sizing.json (rebuilt by tools/build_sizing.py). Memory is MB (MiB),
docker-style used. CPU is % of the whole N100 (4 cores = 100 %).
1. The floor — the box with no apps
| Part | Memory | Disk |
|---|---|---|
Whole host (Proxmox + agent + guest + platform), MemTotal − MemAvailable |
2,494 MB (peak 2,793) | host root 31 GB used of 94 GB, of which 19 GB = 3 local guest dumps |
| — of which inside the guest: platform containers + Docker daemons | ≈ 470 MB | guest system 1.1 GB, Docker volume 1.6 GB (platform images 1.55 GB) |
| traefik (proxy) | 113 MB (anon 15) | — |
| filebrowser (file browser) | 75 MB (anon 18) | — |
| cloudflared (tunnel) | 38 MB (anon 16) | — |
| felhom-controller | 29 MB (anon 28) | — |
| dockerd + containerd + shims | ≈ 220 MB RSS | — |
| CPU at rest, platform only | 0.4 % of the N100 | — |
| Power at rest (CPU package, approximate) | 3.9 W | — |
Samba is not in the floor: it runs only when sharing is switched on. Evidence: evidence/floor/.
2. Each app
| App | Typical MB | Peak MB | Catalog request / limit | CPU class | CPU rest % | Busiest minute % | Source |
|---|---|---|---|---|---|---|---|
Immich (immich) |
1,356 | 3,061 | 2,048 / 4,480 | heavy-in-bursts | 0.74 | 74.2 | onboarding ! |
Grimmory (grimmory) |
346 | 1,095 | 600 / 1,408 | medium | 0.83 | 22.0 | onboarding ! |
Karakeep (karakeep) |
361 | 1,050 | 700 / 2,816 | light | 0.6 | 2.9 | onboarding ! |
Cal.com (calcom) |
800 | 950 | 200 / 1,792 | light | 0.14 | 1.8 | onboarding |
Dawarich (dawarich) |
390 | 890 | 500 / 2,688 | light | 0.48 | 14.4 | onboarding |
Tandoor Recipes (tandoor) |
868 | 868 | 512 / 1,280 | medium | 0.16 | 20.0 | onboarding |
RomM (romm) |
528 | 769 | 300 / 1,280 | medium | 0.71 | 24.2 | telemetry |
SparkyFitness (sparkyfitness) |
305 | 664 | 400 / 1,792 | light | 0.23 | 0.4 | onboarding ! |
Paperless-ngx (paperless-ngx) |
568 | 659 | 500 / 1,664 | medium | 0.37 | 31.3 | telemetry |
n8n (n8n) |
321 | 550 | 512 / 1,536 | light | 0.1 | 0.5 | onboarding ! |
Nextcloud (nextcloud) |
314 | 525 | 256 / 1,664 | light | 0.4 | 12.8 | onboarding ! |
Komga (komga) |
442 | 496 | 200 / 768 | light | 0.15 | 0.5 | onboarding |
Docmost (docmost) |
415 | 495 | 200 / 896 | light | 0.38 | 0.8 | telemetry |
OnlyOffice (onlyoffice) |
364 | 488 | 512 / 2,048 | medium | 0.04 | 31.8 | measured |
Rallly (rallly) |
360 | 479 | 384 / 1,024 | light | 0.19 | 2.9 | onboarding |
AdventureLog (adventurelog) |
361 | 464 | 100 / 896 | medium | 0.45 | 19.3 | telemetry |
Grafana (grafana) |
220 | 435 | 100 / 512 | light | 0.31 | 1.0 | onboarding ! |
Mealie (mealie) |
273 | 431 | 200 / 1,000 | light | 0.15 | 1.4 | onboarding ! |
Calibre-Web Automated (calibre-web) |
191 | 413 | 200 / 768 | medium | 0.04 | 26.0 | telemetry ! |
Papra (papra) |
266 | 405 | 256 / 768 | light | 0.07 | 0.2 | onboarding |
Outline (outline) |
282 | 393 | 200 / 1,152 | light | 0.39 | 1.4 | onboarding |
Jellyfin (jellyfin) |
191 | 373 | 512 / 2,048 | heavy-in-bursts | 0.06 | 51.3 | measured |
Gramps Web (gramps-web) |
326 | 342 | 384 / 1,024 | light | 0.04 | 0.0 | onboarding |
MeTube (metube) |
62 | 329 | 128 / 768 | light | 0.03 | 0.1 | onboarding ! |
Home Assistant (home-assistant) |
318 | 328 | 256 / 1,024 | light | 0.2 | 2.4 | onboarding |
qBittorrent (qbittorrent) |
163 | 318 | 192 / 1,024 | light | 0.04 | 0.1 | onboarding ! |
wger (wger) |
246 | 267 | 256 / 416 | — | – | – | onboarding — hidden |
Plant-it (plant-it) |
50 | 256 | 50 / 256 | — | – | – | unmeasured — abandoned |
Claper (claper) |
248 | 248 | 100 / 640 | light | 0.3 | 0.5 | onboarding |
Kimai (kimai) |
163 | 240 | 100 / 640 | light | 0.16 | 0.8 | telemetry ! |
Plex (plex) |
232 | 234 | 512 / 2,048 | light | 0.22 | 3.4 | measured |
Uptime Kuma (uptime-kuma) |
103 | 227 | 50 / 256 | light | 0.2 | 0.2 | onboarding ! |
BookStack (bookstack) |
159 | 225 | 150 / 768 | light | 0.18 | 0.9 | telemetry ! |
Zipline (zipline) |
196 | 217 | 100 / 768 | light | 0.2 | 0.3 | onboarding |
Wishlist (wishlist) |
115 | 184 | 120 / 512 | light | 0.07 | 0.1 | onboarding ! |
Jellyseerr (seerr) |
166 | 168 | 100 / 384 | light | 0.04 | 0.1 | measured |
ActualBudget (actualbudget) |
44 | 167 | 50 / 256 | light | 0.06 | 0.1 | measured ! |
Ghost (ghost) |
149 | 149 | 150 / 512 | light | 0.08 | 0.2 | onboarding |
Wanderer (wanderer) |
143 | 147 | 350 / 1,024 | light | 0.2 | 0.3 | measured |
Emby (emby) |
142 | 146 | 512 / 2,048 | light | 0.18 | 1.9 | onboarding ! |
Gitea (gitea) |
74 | 136 | 100 / 512 | light | 0.04 | 0.1 | onboarding ! |
Homebox (homebox) |
17 | 118 | 50 / 256 | light | 0.06 | 0.1 | measured ! |
Termix (termix) |
102 | 117 | 30 / 128 | light | 0.04 | 0.1 | measured |
Grocy (grocy) |
30 | 114 | 60 / 384 | light | 0.04 | 0.3 | onboarding ! |
LubeLogger (lubelogger) |
53 | 113 | 80 / 512 | light | 0.08 | 0.3 | onboarding ! |
Vikunja (vikunja) |
20 | 104 | 50 / 256 | light | 0.0 | 0.0 | measured ! |
Radarr (radarr) |
96 | 100 | 150 / 512 | light | 0.09 | 0.3 | measured |
Vaultwarden (vaultwarden) |
44 | 99 | 50 / 256 | light | 0.03 | 0.0 | onboarding ! |
Crafty Controller (crafty-controller) |
78 | 84 | 256 / 2,048 | light | 0.09 | 0.2 | onboarding ! |
Homepage (homepage) |
82 | 83 | 50 / 256 | light | 0.03 | 0.0 | measured |
Gokapi (gokapi) |
7 | 77 | 30 / 128 | light | 0.03 | 0.0 | measured ! |
Sonarr (sonarr) |
77 | 77 | 150 / 512 | light | 0.07 | 0.2 | onboarding |
Recipe Importer (recipe-importer) |
63 | 72 | 30 / 128 | light | 0.09 | 0.1 | measured |
OpenGist (opengist) |
27 | 68 | 30 / 128 | light | 0.03 | 0.8 | telemetry |
SABnzbd (sabnzbd) |
68 | 68 | 192 / 1,024 | light | 0.04 | 0.1 | onboarding |
Code-Server (code-server) |
59 | 59 | 200 / 1,024 | light | 0.03 | 0.0 | measured |
PrivateBin (privatebin) |
40 | 59 | 30 / 128 | light | 0.04 | 0.0 | telemetry ! |
Audiobookshelf (audiobookshelf) |
48 | 54 | 100 / 512 | light | 0.04 | 0.1 | onboarding |
Radicale (radicale) |
27 | 27 | 40 / 128 | light | 0.03 | 0.0 | onboarding |
Transmission (transmission) |
6 | 22 | 64 / 512 | light | 0.05 | 0.1 | onboarding ! |
Navidrome (navidrome) |
14 | 18 | 50 / 256 | light | 0.04 | 0.1 | onboarding |
BentoPDF (bentopdf) |
5 | 10 | 100 / 384 | light | 0.03 | 0.0 | telemetry ! |
Glance (glance) |
6 | 7 | 20 / 128 | light | 0.03 | 0.0 | measured |
NZBGet (nzbget) |
5 | 5 | 64 / 512 | light | 0.04 | 0.1 | onboarding |
source: telemetry = hub fleet data ≥ 7 days · onboarding = an earlier session's measured peak · measured = this bench ·
unmeasured = catalog value. ! = two sources' peaks differ by more than 50 %; the higher is used (all values:
evidence/apps-table.json). — = not installable today (hidden / abandoned), no bench.
The five largest peaks: Immich 3,061 · Grimmory 1,095 · Karakeep 1,050 · Cal.com 950 · Dawarich 890 MB. CPU bursts (heavy-in-bursts): Immich — 74 % for the busiest minute, while it reads new photos; Jellyfin — 51 %, while it converts a film (CPU only, no GPU passed through). Medium: Paperless-ngx 31 % (reading scans), OnlyOffice 32 %, Calibre-Web 26 %, RomM 24 %, Grimmory 22 %, Tandoor 20 %, AdventureLog 19 % (first start). Every other app stays under 15 % even at first start.
3. Catalog accuracy (§7 C — templates NOT changed; evidence/catalog-check.json)
Near a memory limit (peak > 80 %) — risk: the container is stopped for using too much memory:
| App | Finding | Source |
|---|---|---|
| docmost | container docmost 475 MB = 93 % of its 512 MB limit |
telemetry + bench |
| romm | container romm 703 MB = 92 % of its 768 MB limit |
telemetry + bench |
| termix | 117 MB = 91 % of its 128 MB limit | bench |
| uptime-kuma | 227 MB = 89 % of mem_limit 256 MB |
telemetry (tester-1) |
| grafana | 435 MB = 85 % of its 512 MB limit | bench |
| immich | container immich-server 1,665 MB = 81 % of its 2,048 MB limit (kernel peak incl. cache 4,365 of 4,480 MB for the app) |
bench, 200-photo import |
| tandoor | container tandoor 827 MB = 81 % of its 1,024 MB limit |
bench |
No container was killed for memory during the bench (oom_kill = 0 in every container).
Typical use above mem_request (the catalog's figure is too low), 23 apps: calcom ×4.0 · adventurelog ×3.6 ·
termix ×3.4 · claper ×2.5 · grafana ×2.2 · komga ×2.2 · docmost ×2.1 · recipe-importer ×2.1 · uptime-kuma ×2.1 ·
zipline ×2.0 · romm ×1.8 · seerr ×1.7 · tandoor ×1.7 · homepage ×1.6 · kimai ×1.6 · mealie ×1.4 · outline ×1.4 ·
privatebin ×1.3 · home-assistant ×1.2 · nextcloud ×1.2 · bookstack ×1.1 · paperless-ngx ×1.1 · papra ×1.0.
4. Power
| State | CPU package (RAPL) | Wall |
|---|---|---|
| Platform at rest, 15 min | 3.9 W | not measured — no meter (operator, 2026-10-13) |
| Immich import, 200 photos + all jobs (411 s) | 12.5 W average, 14.7 W busiest minute; 70 °C max | not measured |
Approximate, CPU only — not wall power. The wall figure adds the board, SSD, HDD, fan and power-supply losses.
5. Proposed minimum machine — a proposal; the operator decides
Worked from: floor + the household set (Immich, Jellyfin, Nextcloud, Home Assistant, Vaultwarden, Paperless-ngx).
| Memory | |
|---|---|
| Household set, typical (sum) | 2,791 MB |
| Household set, all at peak at once (sum — they rarely coincide; deliberately pessimistic) | 5,045 MB |
| Guest platform | ≈ 470 MB |
| Guest needs at peak | ≈ 5.5 GB |
| + 50 % headroom | ≈ 8.3 GB guest |
| + the host's share (the installer keeps 4 GB for Proxmox; it used ≈ 2.0 GB here) | ≈ 12.3 GB box |
Headroom 50 %, because: the bench library is small (200 photos; tester-1's real Immich already peaked at 2.9 GB); the nightly backup runs database dumps and restic next to the apps; an update pulls new images while the old ones run; and the page cache is what makes a photo library feel fast.
| Minimum | Recommended | |
|---|---|---|
| CPU | x86-64, 4 cores, N100 class or newer (Intel or AMD) | N100 / N150 / N305 or better; Intel Quick Sync helps Jellyfin later (not used today) |
| Memory | 8 GB | 16 GB |
| System disk | 256 GB SSD | 512 GB SSD (NVMe or SATA) |
| Data | a separate drive for photos and films | same |
| Out | ARM (Raspberry Pi), Synology / QNAP and other NAS appliances, routers, cloud VPS, 32-bit machines | — |
Disk, why: the installer gives the guest a 32 GB system volume and, from the free space, a 70 / 130 / 250 GB data volume; the host keeps three daily guest dumps (19 GB on this box). Image sizes per app were not measured in this run.
What each size runs (the installer gives the guest: 8 GB → 4 GB, 16 GB → ≈ 11.6 GB, 32 GB → ≈ 27.6 GB):
- 8 GB: the household set without Immich (peaks 2.0 GB + platform) with room to spare; Immich only on its own or with one or two light apps (its import alone peaks at 3.1 GB of the guest's 4 GB). The floor of the offer.
- 16 GB: the whole household set at peak (≈ 5.5 GB) twice over, plus a dozen light apps. The recommended box.
- 32 GB: the household set plus most of the catalog: all 62 installable apps typical together ≈ 13.3 GB, at peak ≈ 21.3 GB.