Files
felhom.eu/documentation/audits/persistence-sweep-2026-10-02/A/papra/SUMMARY.md
T

2.8 KiB
Raw Blame History

R-803 — papra OOM under its 256M limit: birth measurement and proposed limit (2026-10-02, bench 9401 on demo-hp)

Bench: LXC 9401 r803-papra on demo-hp (debian-13 amd64, swap 0, nesting+keyctl, 60G rootfs on nvme-scratch, 12 GiB). Code: catalog-wt febf58c + the uncommitted gate scripts. Image ghcr.io/papra-hq/papra:26.6.2-rootless. Driver: r803_birth.py (scratchpad). It deploys the template the way the volume gate does (same build_env, same scratch paths, docker compose create then start), samples the container's cgroup v2 every 2 s from creation (memory.stat anon/file, memory.current, memory.peak, memory.events oom/oom_kill/max, plus docker status/health/ restarts/OOMKilled), seeds once and reads back once with papra's own upgrade fixture (upgrade_fixtures_box.Papra through upgrade_boxport.get), then idles 300 s. No Docker Hub login this time: the papra pull is from ghcr, and the canary base image pulled anonymously.

1. From birth, no limit (birth-unlimited/)

The deploy block was removed in a separate run copy of the catalog (HostConfig.Memory=0).

  • healthy at 71.5 s (the image pull is included in that time), 0 restarts, oom_kill 0
  • peak anon 425,029,632 B = 405.3 MiB, sampled during first start/migration (4–28 s after start)
  • peak memory.current 427 MiB; the cgroup's own memory.peak (anon + file, catches what 2-s sampling misses) 483 MiB
  • after healthy: anon ~356 MiB for ~2 min, then settles at ~254 MiB idle, which is already near the old 256M limit
  • fixture: papra: sign-up http=200 → seed OK; papra: sign-in as the seeded account http=200 ok=True → read back true
  • volume after the run: db/db.sqlite (581632 B) in the /app/app-data volume

2. Proposed limit

405.3 MiB × 1.6 = 648 MiB → next catalog step 768M. 768M also covers the highest memory.peak seen (483 MiB) at 1.59×. The bench template diff is in template.diff. It is NOT applied to the repo.

3. From birth at 768M (run-768M/)

  • HostConfig.Memory=805306368 (768 MiB); memory.max = 805306368
  • healthy at 31.0 s, final status running/healthy, restarts 0, oom_kill 0, OOMKilled false
  • fixture seed OK, read back true
  • peak anon 297,943,040 B = 284.1 MiB, memory.peak 341 MiB, idle end anon 251 MiB. This run peaked lower than the unlimited run: the start-up peak varies between runs (memory.peak 341–483 MiB over two runs), so do not size from one run.
  • gate (gate-papra-768M.txt, probe in gate-evidence/papra/probe.json), verbatim: papra CLEAN / 1 clean · 0 broken · 0 undetermined (of 1 in scope) / volume-persistence gate OK / check-volume-persistence exit code = 0. Exercise 172.18.0.2:1221/ -> 200; /app/app-data holds db/db.sqlite.

Note: mem_request: "50M" in .felhom.yml was left unchanged (not in scope). Measured idle is ~255 MiB.