The warm-up reads every session file for the Sessions page and Usage › Requests. On a 13.5k-session history it allocates ~830 MB (QueryPage ~570, StatsFor ~260) to keep ~80 MB of indexes, and Go's scavenger returns the freed pages only over the next minutes. warmUp now calls debug.FreeOSMemory once its reads are done: one forced GC and scavenge, once, at start.
RSS of a linux nogui `magpie web` in Docker on a copy of a real config with those sessions mounted read-only, sampled every 15 s from start (with the dsh round change before it): 15 s 472 -> 197 MB, 30 s 475 -> 285, 60 s 417 -> 281, 2 min 337 -> 281, 3.5 min 266 -> 218, 12 min ~250 -> ~204. TestWarmUpReturnsItsGarbage fails without the FreeOSMemory call (10 of 10: 46-334 MB of freed heap still held, or the heap not yet collected) and passes 10 of 10 with it. go test -tags nogui ./internal/gui ./internal/sessions (Docker golang:1.26.8, temp HOME), go vet -tags nogui ./internal/gui for linux, windows and darwin, and gofmt -l pass. Not measured on macOS: a fresh build there hangs at exec behind syspolicyd today.