16 KiB
Sizing check 2026-10-14 — do the estimator's numbers hold on a second machine, with apps together?
Box: demo-hp (AMD Ryzen Embedded V1756B, 4 cores / 8 threads, 29,994 MiB), guest 9201. Tools: the sizing bench
(sizing-2026-10-13/tools/: bench.py, guest_sampler.sh, host_sampler.sh, actions.sh) pointed at demo-hp — only the
box constants change. „Page says" figures are computed with scripts/test_build_sizing_web.py's mirror of sizing.js
on website/assets/sizing-data.json (no JavaScript runtime on DooPlex). Deploys through the product; path fields take
their default (the enrolled drive). The box already runs 11 apps of its own (Home Assistant and Paperless among them);
they stay, and they are measured as they are.
Predictions (written 00:20 UTC, before any deploy)
| Item | Page says | Prediction |
|---|---|---|
| „Just files and passwords" at rest (nextcloud + vaultwarden) | typical 314 + 44 MB; peak 525 + 99 MB | measured rest below the page's typical (N100 figures were taken idle) — 250–400 MB together |
| Immich during a 200-photo import, with the others busy too | peak 3,061 MB | 2.0–3.0 GB (the HP's faster CPU ends the ML jobs sooner, the peak is the same model loading) |
| Jellyfin forced transcode | peak 373 MB | 300–600 MB (used counts the file cache of the video) |
| Paperless 20 scans (consume folder) | peak 659 MB | 600–900 MB (OCR workers) |
| The set's real peak, all working at once, vs the page's sum of peaks (5,045 MB + platform 470) | 5,515 MB | the real simultaneous peak is 60–80 % of the sum — the page's „all at peak at once" is pessimistic, as it says |
| Platform (controller, traefik, cloudflared, filebrowser) | 470 MB | 350–500 MB |
R1 — the numbers together (evidence evidence/R1-set/, summary set-summary.json)
Windows (UTC): rest A 00:18:02–00:48:02 (files + passwords only; the 00:30 db-dump falls inside); together
00:51:00–00:54:44 (Immich 200-photo import + its ML jobs, Jellyfin scan + forced 1080p transcode, Nextcloud 50 × 10 MiB
WebDAV upload — all three at once); Paperless 20 scans 01:01:40–01:08:33 (alone: the bench first put the scans in a
sub-folder, which Paperless does not read — moved at 01:01:40); rest B 01:08:40–01:29:30. used = memory.current −
inactive_file, per app summed over its containers (the sizing run's definition). No OOM kill anywhere (memory.events).
| App | Page typical | HP rest (median) | Diff | Page peak | HP peak (used) |
Diff | HP memory.peak (incl. file cache) |
|---|---|---|---|---|---|---|---|
| immich | 1,356 | 1,557 | +15 % | 3,061 | 3,290 (during the import) | +7 % | 4,366 |
| jellyfin | 191 | 188 | −2 % | 373 | 448 (transcode) | +20 % | 497 |
| nextcloud | 314 | 229 | −27 % | 525 | 290 | −45 % | 808 |
| home-assistant (the box's own) | 318 | 352 | +11 % | 328 | 434 (after the 00:09 start) | +32 % | 441 |
| vaultwarden | 44 | 37 | −16 % | 99 | 40 | −60 % | 45 |
| paperless-ngx (the box's own) | 568 | 645 | +14 % | 659 | 755 (OCR) | +15 % | 903 |
| platform containers (controller, traefik, cloudflared, filebrowser) | 255 of the page's 470 (the other ~220 MB are the Docker daemons, not in any container — build_sizing_web.py) |
262 (rest B) – 347 (rest A) | +3 to +36 % | — | 386 | — | — |
| The set | Page (site rule) | Measured on the HP | Difference |
|---|---|---|---|
| „Just files and passwords": typical (sum) | 358 (+ platform 470 = 828) | 210 at rest (rest A); 265 after use | −41 % / −26 % |
| „Just files and passwords": peak | 624 (+ 470 = 1,094) | 326 (the 00:30 db-dump) | −48 % |
| „Family starter set": typical (sum) | 2,791 | 3,007 (rest B) | +8 % |
| „Family starter set": peak — the page's sum of peaks vs the real peak with three heavy apps busy at once | 5,045 (+ 470 = 5,515) | 4,900 at 00:52:35 (Paperless at rest then; with its OCR at the same time it would be ~5,100) | −3 % (≈ −0 % with Paperless) |
| platform | 470 (containers 255 + Docker daemons ~220) | containers 262–386; the daemons not sampled | the container part matches; the whole not measured |
| host's share (page: box − guest) | 32 GB box: 4,708 MB (box − guest 28,060 MiB) | not separable here: the HP host also runs Tester 1's 8 GB VM. Host used (MemTotal − MemAvailable) 13.4 GB in rest B, of which the guest's anon 3.8 GB | — |
Prediction check: „the real simultaneous peak is 60–80 % of the sum" — wrong. It was 97 %. Immich's import peak alone is 65 % of the set's peak, and it coincides with Jellyfin's transcode and Nextcloud's upload as soon as a family uses the box at the same time. The page's „all at peak at once" is not pessimistic for this set; it is about right. The light apps (Nextcloud, Vaultwarden) are over-stated (corrected 07:30: an earlier draft compared the platform's containers with the whole 470 MB, which includes the Docker daemons); Immich, Jellyfin, Home Assistant are under-stated.
Second opinions for free — the box's own apps, sampled in the same run
Five of the 24 weakest page figures (source telemetry or onboarding and the sources disagree,
sizing-2026-10-13/evidence/apps-table.json) are apps this box already runs; R1 sampled them all night.
| App | Page source | Page typical | HP rest (median, rest B) | Diff | Page peak | HP peak (used, whole run, incl. the 00:09 start) |
Diff |
|---|---|---|---|---|---|---|---|
| bookstack | telemetry | 159 | 148 | −7 % | 225 | 222 | −1 % |
| calibre-web | telemetry | 191 | 161 | −16 % | 413 | 242 | −41 % |
| kimai | telemetry | 163 | 155 | −5 % | 240 | 250 | +4 % |
| privatebin | telemetry | 40 | 38 | −5 % | 59 | 60 | +2 % |
| bentopdf | telemetry | 5 | 10 | +100 % (5 MB) | 10 | 15 | +50 % (5 MB) |
R3 — are the page's three answers true on an 8 GB box?
Where (decided by CC, 03:15): scratch guest 9202, not 9201. 9201 runs 11 apps of its own (2.6 GB at rest) that the
page's selection does not include; on a 4 GB guest they would decide the result. 9202 holds only the platform and a
Paperless — what the page models: the box plus the selected apps. Paperless is stopped for the first two selections and
started for the family set (it is part of it). Memory: pct set 9202 --memory 4096 (the installer's
autosize_guest_caps() for an 8 GB box, = the page's guestMib(8); was 25,898), swap 512 (Proxmox's default; the
installer sets none). Restart: the dashboard's restart answered 503 „agent not configured" — 9202 has no agent link
by design — so pct reboot 9202.
Predictions (03:19, before any deploy):
| Selection | Page says on 8 GB | Prediction |
|---|---|---|
| „Just files and passwords" | fits well | fits: no OOM kill, no swap, upload as fast as on 9201 |
| Immich alone | fits, but tight | works: no OOM kill; some swap during the ML jobs; the import 10–50 % slower than on 9201 |
| „Family starter set" | does not fit | real harm while all work at once: swap full, at least one OOM kill (most likely Immich's machine learning) or an app restart, the actions much slower |
R3 results (evidence evidence/R3-8gb/, evidence/R3b-family/; counters from the guest cgroup lxc/9202)
The deploy itself warned from the second app on: „Az alkalmazások csúcsterhelése meghaladhatja a rendelkezésre álló
memóriát…" (Immich alone and every family app; not for files + passwords) — the product's own check agrees with the page.
„Hit the 4 GB limit" (memory.events max) happens in every selection — that is the file cache being reclaimed, not harm.
| Selection | Page says on 8 GB | OOM kills | Swap (512 MB) | The action | Every app answers? | Measured result |
|---|---|---|---|---|---|---|
| „Just files and passwords" | fits well | 0 | 19 MB | Nextcloud 50 × 10 MiB upload: 28 s, 50/50 | yes | fits well — true |
| Immich alone | fits, but tight | 14 — all in Immich's machine-learning container, at its own 1.5 GiB catalog limit (the same limit was reached on the big guest without a kill) | full (512 MB peak) | 200-photo import + jobs: 295 s (big guest: 221 s with two other apps busy), 200/200 | yes | tight — true; it works, slower, with ML workers killed and restarted |
„Family starter set", run 1 (5 of 6: Nextcloud refused at install — its old data from run 1 was kept, 409 kept_data_choice) |
does not fit | +2 | full; load average 151 on 4 cores | Immich upload 196/200 in 7.5 min (immich-server restarted); Paperless 20/20 |
yes, after | harm |
„Family starter set", run 2 (all 6, R3b-family) |
does not fit | +4 (20 since the start) | full | Immich 116/200 (84 failed; immich-server restarted); Jellyfin transcode 1,322 s (big guest: 87 s); Nextcloud 49/50 (one 503); Paperless 0/20 in 30 min |
yes, after the work | does not fit — true: real harm |
All three answers held on the 8 GB box. The prediction for „Immich alone" (no OOM kill) was wrong: the ML container is killed at its own limit when the guest is short of memory.
R2 — the night backup next to the family set (evidence evidence/R2-night/, 01:32–02:51 UTC)
Tier 2 (01:30, 12 s) fell between the two samplings; Tier 1 (00:30, the database dumps) fell in R1's rest A. The apps on 9201 at the time: the box's 11 + the bench's 4 (immich, jellyfin, nextcloud, vaultwarden).
| Window (UTC) | Controller container (Tier 3's restic runs inside it) | All apps in the guest (used) |
Host used (MemTotal − MemAvailable) | Host CPU busy |
|---|---|---|---|---|
| quiet, 01:35–02:14 | 189 MB median, 209 max | 4,370 median | 13,323 median | 9 % median |
| Tier 3 restic → Storage Box, 02:15–02:18 (3 min 27 s, 11 apps, 120 snapshots) | 170 median, 308 max (+~120 MB) | 3,901 median, 4,361 max | 12,943 median, 13,463 max | 30 % median, 69 % max |
| whole-guest vzdump on the HOST, 02:42–02:51 (cut by R3) | 84 median (the quiesce pauses apps) | 3,654 median | 13,480 median, 14,619 max (+~1.1 GB, on the host) | 25 % median, 100 % max |
| Tier 1 db dumps, 00:30 (R1 rest A) | — | „files + passwords" peaked at 326 MB then (+~115 MB over its rest) | — | — |
What the 1.5 headroom is for, measured: inside the guest the backups add little — about 120 MB for Tier 3's restic and about 115 MB for a database dump; apps do not grow during them. The big one, the whole-guest vzdump + zstd, runs on the host, outside the guest's memory: +1.1 GB of host memory. On an 8 GB box the host keeps about 4 GB (box − guest), so it fits there. So the backups use a small part of the headroom; on this box the headroom was really used by the apps' own peaks working at once (R1) — and on 4 GB that is not enough (R3).
R4 — second opinions for the weakest figures (evidence evidence/R4-b1..b4/, summary.json from the sizing run's analyze.py)
The 24 weakest page figures (apps-table.json: source onboarding or telemetry and the sources disagree): 3 were
measured in R1 (immich, nextcloud, vaultwarden), 5 are the box's own apps (table above), the other 16 ran here in four
batches on scratch guest 9202 at full memory (06:00–07:25 UTC): deployed through the product, 15 min at rest, removed
(no leftovers). These are light batches — no action (as the sizing run's light batches): the rest figure is a fair
second opinion; the „peak" here is only the start-up peak, so a page peak that includes real work reads higher.
| App | Page source | Page typical | HP rest | Diff | Page peak | HP peak (rest batch, no action) | Diff | OOM |
|---|---|---|---|---|---|---|---|---|
| grafana | onboarding | 220 | 269 | +22 % | 435 | 383 | -12 % | 0 |
| grimmory | onboarding | 346 | 451 | +30 % | 1095 | 624 | -43 % | 0 |
| karakeep | onboarding | 361 | 372 | +3 % | 1050 | 643 | -39 % | 0 |
| mealie | onboarding | 273 | 226 | -17 % | 431 | 240 | -44 % | 0 |
| n8n | onboarding | 321 | 351 | +9 % | 550 | 578 | +5 % | 0 |
| sparkyfitness | onboarding | 305 | 316 | +4 % | 664 | 410 | -38 % | 0 |
| uptime-kuma | onboarding | 103 | 118 | +15 % | 227 | 119 | -48 % | 0 |
| wishlist | onboarding | 115 | 118 | +3 % | 184 | 121 | -34 % | 0 |
| crafty-controller | onboarding | 78 | 79 | +1 % | 84 | 80 | -5 % | 0 |
| emby | onboarding | 142 | 136 | -4 % | 146 | 142 | -3 % | 0 |
| gitea | onboarding | 74 | 76 | +3 % | 136 | 89 | -35 % | 0 |
| grocy | onboarding | 30 | 33 | +10 % | 114 | 34 | -70 % | 0 |
| lubelogger | onboarding | 53 | 56 | +6 % | 113 | 65 | -42 % | 0 |
| metube | onboarding | 62 | 62 | +0 % | 329 | 63 | -81 % | 0 |
| qbittorrent | onboarding | 163 | 18 | -89 % | 318 | 18 | -94 % | 0 |
| transmission | onboarding | 6 | 6 | +0 % | 22 | 7 | -68 % | 0 |
At rest, 14 of 16 agree within ±30 %. Two differ: grimmory +30 % (451 vs 346) and qbittorrent −89 % (18 vs 163 — idle with no torrent; the page's figure is from a household's onboarding note with torrents running, so the HP figure is the weaker one here). No OOM kill.
Apps that differ from the page by more than 30 % (one line each)
| App | Figure | Page | HP | Basis |
|---|---|---|---|---|
| nextcloud | peak | 525 | 290 (−45 %) | 50 × 10 MiB upload, alone and with others |
| vaultwarden | peak | 99 | 40 (−60 %) | light use |
| home-assistant | peak | 328 | 434 (+32 %) | the start after a boot |
| calibre-web | peak | 413 | 242 (−41 %) | the box's own, all night |
| grimmory | typical | 346 | 451 (+30 %) | rest batch |
| qbittorrent | typical | 163 | 18 (−89 %) | rest batch, no torrents |
| bentopdf | typical / peak | 5 / 10 | 10 / 15 | +5 MB only |
Proposal — for the operator; nothing on the website changed tonight
One answerable question: should the page's figures move with tonight's measurements?
| Option | What changes | Cost | If nothing is done |
|---|---|---|---|
| A (recommended) — small figure update | Immich peak 3,061 → 3,300; Jellyfin peak 373 → 450; Home Assistant peak 328 → 435; Nextcloud peak 525 → 300; Vaultwarden peak 99 → 45; Grimmory typical 346 → 450. Keep the headroom (1.5), the platform (470) and every verdict | one data edit + the page's data file rebuilt; the „Family starter set" peak moves +144 MB (5,515 → 5,659): its verdicts stay (8 GB no, 12 GB tight, 16 GB well) | the page stays inside ±10 % for the family set; three apps keep a peak that reads low |
| B — also a sentence for Immich on 8 GB | „Immich works on 8 GB, but its face and search jobs restart under memory pressure" next to the „tight" verdict | one string in two languages | a household on 8 GB with Immich sees slow, restarting background jobs with no explanation |
The three answers on an 8 GB box were all true (R3): files + passwords fit well (0 OOM kills), Immich alone is tight (it works; 14 OOM kills in its ML container, swap full), the family set does not fit (84 of 200 photo uploads failed, transcode 15× slower, Paperless did nothing in 30 min). The headroom of 1.5 is not too strict: the family set's real simultaneous peak was 97 % of the page's sum. Register row R-1009.
2026-10-14 — the operator's „raise only" ruling, built and STOPPED before the push
The rule was built as a source (raise-only-source.patch for sizing-2026-10-13/tools/build_sizing.py; the HP figures
from the evidence by tools/hp_figures.py → hp-figures.json, 27 apps, used basis). It raises 23 figures and lowers none
(Immich typical 1,356 → 1,557 and peak 3,061 → 3,290; Jellyfin peak 373 → 448; Home Assistant 318 → 352 / 328 → 434;
Paperless 568 → 645 / 659 → 755; Grimmory typical 346 → 451; and 17 small ones). The presets keep their verdicts (family
5,515 → 6,021 MB: 8 GB no, 12 GB tight, 16 GB well; files + passwords 1,094 unchanged; Immich alone 3,531 → 3,760: 8 GB tight).
But one verdict of the SIZING.md §5 table changes: „Household set without Immich" on 8 GB — fits well → fits, but
tight. Its peak becomes 2,731 MB; × 1.5 = 4,096.5 MB against the 8 GB guest's 4,096 MB: 0.5 MB over. Not one figure
does it: without the Jellyfin raise, or the Home Assistant raise, or the Paperless raise, it stays „fits well". By the
task's STOP rule the website was not pushed; the data changes were reverted (nothing half-built is committed).
| Option | What happens | Cost |
|---|---|---|
| A — publish the raise as ruled; accept the one changed verdict | „5 apps without Immich on 8 GB" reads „fits, but tight"; SIZING.md §5 and the test case updated |
the page is 0.5 MB pessimistic there |
| B — raise only, but round the HP figures to the nearest 10 MB down | to be checked: it may still flip | one rule sentence |
| C — keep today's figures | nothing changes; the HP's higher figures stay unused | the page reads low for Immich, Jellyfin, Home Assistant, Paperless |