# 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,557 | 3,983 (raised 2026-10-18) | 2,048 / 4,480 | heavy-in-bursts | 0.74 | 74.2 | onboarding ! | | Grimmory (`grimmory`) | 451 | 1,095 | 600 / 1,408 | medium | 0.83 | 22.0 | onboarding ! | | Karakeep (`karakeep`) | 372 | 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 | | Paperless-ngx (`paperless-ngx`) | 645 | 755 | 500 / 1,664 | medium | 0.37 | 31.3 | telemetry | | SparkyFitness (`sparkyfitness`) | 316 | 664 | 400 / 1,792 | light | 0.23 | 0.4 | onboarding ! | | n8n (`n8n`) | 351 | 578 | 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 | | Jellyfin (`jellyfin`) | 191 | 448 | 512 / 2,048 | heavy-in-bursts | 0.06 | 51.3 | measured | | Grafana (`grafana`) | 269 | 435 | 100 / 512 | light | 0.31 | 1.0 | onboarding ! | | Home Assistant (`home-assistant`) | 352 | 434 | 256 / 1,024 | light | 0.2 | 2.4 | 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 | | 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 ! | | 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 | | Kimai (`kimai`) | 163 | 250 | 100 / 640 | light | 0.16 | 0.8 | telemetry ! | | Claper (`claper`) | 248 | 248 | 100 / 640 | light | 0.3 | 0.5 | onboarding | | Plex (`plex`) | 232 | 234 | 512 / 2,048 | light | 0.22 | 3.4 | measured | | Uptime Kuma (`uptime-kuma`) | 118 | 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`) | 118 | 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`) | 76 | 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`) | 33 | 114 | 60 / 384 | light | 0.04 | 0.3 | onboarding ! | | LubeLogger (`lubelogger`) | 56 | 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`) | 79 | 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 | | PrivateBin (`privatebin`) | 40 | 60 | 30 / 128 | light | 0.04 | 0.0 | telemetry ! | | Code-Server (`code-server`) | 59 | 59 | 200 / 1,024 | light | 0.03 | 0.0 | measured | | 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`) | 10 | 15 | 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,983 (3,290 until 2026-10-18) · Grimmory 1,095 · Karakeep 1,050 · Cal.com 950 · Dawarich 890 MB. **Raised with the HP check (2026-10-14, operator ruling A, R-1009):** 23 figures of 64 apps took the second machine's higher figure (HP t740, `audits/sizing-check-2026-10-14/hp-figures.json`); none went down. Each raised figure is named in `sizing.json` → `raised_by_hp` (the figure, what it was, what it is). The table above already holds the raised figures. **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 Wall figures: the whole N100 box at the socket (Tuya meter plug, tinytuya, 2 s; `audits/poweroff-2026-10-13/`, measured the same evening). CPU figures: Intel RAPL, CPU package only (this run). | State | Wall (plug) | CPU package (RAPL) | |---|---|---| | Platform at rest | **8.5 W** average, 7.2 W median (10 min) | 3.9 W (15 min) | | Immich import, 200 photos + all jobs | **20.7 W** average, 24.0 W busiest minute, 25.2 W max (442 s) | 12.5 W average, 14.7 W busiest minute; 70 °C max (411 s) | | Switched off (host powered off, plug on) | **0.0 W** — below the plug's 0.1 W step (18 min) | — | | **One real night, the N100** (2026-10-13 22:12 → 06:00, its normal night: dumps, Tier 2, Tier 3, whole-guest backup, OS steps) | **66 Wh in 7.8 h** — 8.5 W average, 7.3 W median, 20.6 W max (the backup window: 19.8 W max); ≈ 0.2 kWh a day | — | | **HP t740 (demo-hp)**, the second machine, at rest (guest 9201 with 11 apps + Tester 1's VM + a scratch guest) | **24–27 W** (median 24.1 W) | — | | HP, three heavy apps busy at once (Immich import, Jellyfin transcode, Nextcloud upload) | 71 W average, 81.6 W max | — | | HP, a start after a power cut (to all apps healthy, ~4 min) | 72–81 W peak, 2.7–3.4 Wh | — | | HP, switched off with the plug on | 0–3.2 W | — | Rough yearly figure at rest: 8.5 W × 8,760 h ≈ 75 kWh (the measured night agrees: 66 Wh in 7.8 h). The N100 night and the HP rows: `audits/night-power-2026-10-13/` (2026-10-14). They are in this table only, not in `sizing.json`: changing that file changes the checksum the website's data file carries, and the website was not to change that night. ## 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) | 3,103 MB | | Household set, all at peak at once (sum — they rarely coincide; deliberately pessimistic) | 5,551 MB | | Guest platform | ≈ 470 MB | | Guest needs at peak | ≈ 5.9 GB | | + 50 % headroom | ≈ 8.8 GB guest | | + the host's share (the installer keeps 4 GB for Proxmox; it used ≈ 2.0 GB here) | **≈ 12.8 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 — three verdicts, the same rule as the estimator page** (`/gepigeny`, `website/assets/sizing.js`). *Corrected 2026-10-13:* the lines here first said an 8 GB box runs Immich „on its own” while this section sizes a box at peak × 1.5 — which Immich alone does not meet on 8 GB ((470 + 3,061) × 1.5 ≈ 5.2 GB > 4 GB), though its peak fits (3.4 GB). Three verdicts say both honestly. The guest is the installer's rule on MemTotal = label − 612 MiB (the 16 GB N100 reports 15,772 MiB): **8 GB → 4.0 GB, 16 GB → 11.4 GB, 32 GB → 27.4 GB** (the first version said 11.6 / 27.6). **Fits well:** peak × 1.5 ≤ guest · **fits, but tight:** peak ≤ guest < peak × 1.5 — works, but a large photo import or a backup at the same time can slow it down · **does not fit:** guest < peak. Peak = 470 MB platform + the apps' peaks summed. | Selection | Peak | 8 GB | 16 GB | 24 GB | 32 GB | |---|---|---|---|---|---| | Household set | 6.6 GB | does not fit | fits well | fits well | fits well | | Household set without Immich | 2.7 GB | fits, but tight | fits well | fits well | fits well | | Immich alone | 4.3 GB | does not fit | fits well | fits well | fits well | | All 63 apps | 22.5 GB | does not fit | does not fit | does not fit | fits, but tight | - **8 GB:** the household set without Immich fits, but tight; Immich alone does not fit (since 2026-10-18); the whole household set does not fit. - **16 GB:** the whole household set fits well. - **32 GB:** the household set fits well; all 63 apps at once fit, but tight. 2026-10-14: raised with the HP check (operator ruling A); one verdict became stricter — household set without Immich on 8 GB, by 0.5 MB. 2026-10-18 (R-1147, operator yes): **Immich's peak raised 3,290 → 3,983 MB** from a 4,000-photo import on scratch guest 9202 (`audits/night-2026-10-18/P6/`: the four containers' `memory.current` summed — it includes file cache, so it sits above `used`; the heap alone peaked at 2,777 MB, and the server was OOM-killed twice at its old 2 GB limit). Typical unchanged (1,557; rest after the import 1,230 heap). One verdict became stricter: **Immich alone on 8 GB — does not fit** (4.3 GB > the 4.0 GB guest).