# 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 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) | — | Rough yearly figure at rest: 8.5 W × 8,760 h ≈ 75 kWh. ## 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 — 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 | 5.4 GB | does not fit | fits well | fits well | fits well | | Household set without Immich | 2.4 GB | fits well | fits well | fits well | fits well | | Immich alone | 3.4 GB | fits, but tight | fits well | fits well | fits well | | All 62 apps | 21.3 GB | does not fit | does not fit | does not fit | fits, but tight | - **8 GB:** the household set without Immich fits well; Immich alone fits, but tight; the whole household set does not fit. - **16 GB:** the whole household set fits well. - **32 GB:** the household set fits well; all 62 apps at once fit, but tight.