Skip to content

Measure interpreter baseline VM at startup for version-stable RLIMIT_AS #24

@rdwj

Description

@rdwj

Problem

The RLIMIT_AS default was hardcoded at 200 MB and worked fine on Python 3.11, but Python 3.12's higher baseline VM usage made the limit too tight (#20). We fixed it by bumping to 512 MB, but the same drift will likely recur on 3.13 or 3.14 — each CPython release tends to grow baseline memory slightly.

Proposal

At app startup (before any /execute requests), measure the current interpreter's baseline virtual memory size and compute RLIMIT_AS dynamically:

rlimit_as = baseline_vm + user_budget

Where user_budget is the configurable part (what we actually want to cap user code at — e.g., 400 MB). The baseline measurement absorbs interpreter version drift automatically.

Measurement approach

On Linux, read /proc/self/statusVmSize at startup. This gives the parent process's virtual memory footprint before any user code runs. The subprocess inherits a similar baseline (it's a fork/exec of the same interpreter), so using the parent's measurement as an approximation is reasonable.

def _measure_baseline_vm_kb() -> int:
    with open("/proc/self/status") as f:
        for line in f:
            if line.startswith("VmSize:"):
                return int(line.split()[1])  # kB
    raise RuntimeError("Could not read VmSize from /proc/self/status")

Fallback

If /proc/self/status isn't available (macOS dev, non-Linux CI), fall back to the current hardcoded default. This keeps local development working without Linux-specific dependencies.

Context

Follow-up from #20 review. Not urgent — the 512 MB default works today — but worth doing before the next CPython version bump.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions