93052884b2
gates / gates (push) Successful in 30s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
36 lines
2.8 KiB
Markdown
36 lines
2.8 KiB
Markdown
# 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.
|