Skip to content

Calibrate memory watchdog prlimit ceilings and decide observe -> enforce rollout #860

Description

@ppat

Context

The workspace pod (8 GiB memory limit) is repeatedly OOMKilled by VS Code Remote Server
memory growth. Because /sys/fs/cgroup/memory.oom.group = 1, a cgroup OOM kills every
process in the container as a group — the IDE, all tmux sessions, and all parallel agent
runs die together. No cgroup-level limit is reachable without privileged: true
(/sys/fs/cgroup is ro, cgroup.subtree_control is empty, cgroup namespace is private,
uid 10001, CapEff = 0), which DESIGN.md's "Unprivileged by default" stance rules out.

PR #859 ships a userspace watchdog (script-memory-watchdog.sh, scripts.tf, the Memory Headroom agent metadata, and DESIGN.md/CLAUDE.md documentation of why a userspace watchdog
exists at all) in observe-only mode: it measures headroom, logs candidate actions, and
sets no prlimit ceilings and sends no signals.

What headroom means here

memory.current reads misleadingly high even on an idle container, so the watchdog computes:

U = anon + shmem + unevictable + slab_unreclaimable + kernel_stack + pagetables + percpu + sock
H = memory.max - U

Measured at rest: memory.current 97% of limit, coder stat mem 63%, true U 23%,
headroom H 6.12 GiB, memory.pressure full avg10 0.00. A naive memory.current > 85%
trigger would fire permanently on an idle container — U gets it right by roughly a factor
of four.

What's open

The proposed soft RLIMIT_DATA ceilings (server-main.js 1.5 GiB, extensionHost 3 GiB,
tsserver 3.5 GiB, other language servers 1 GiB, fileWatcher 1 GiB, ptyHost never limited)
are a starting proposal derived from role and the 8 GiB budget, not from measurement.
They are not yet agreed and nothing sets them today. Too low silently kills a healthy
extension host mid-edit; too high makes the mechanism inert.

Acceptance criteria

  • Collect at least a week of L0 calibration data (U and its components, logged by the
    observe-only watchdog) with the workspace under normal use.
  • Agree L2/L3 prlimit thresholds from the observed distribution rather than the
    starting proposal.
  • Decide and execute the observe -> enforce transition (the mode switch introduced in
    PR feat: add observe-only memory watchdog to the workspace template #859).
  • Re-run the test_mode negative test: drive headroom below the L4 floor from outside
    the --type=ptyHost subtree and confirm the VS Code Remote Server tree dies while a
    coder ssh-attached tmux session and the coder agent process survive, with
    memory.events.oom_group_kill not incrementing.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions