Podman cgroup v2 Resource Limits & OOM Diagnosis Prompt
Set correct memory, CPU, and PID limits for Podman containers under cgroup v2 and trace exactly why a container was OOM-killed or CPU-throttled.
- Target user
- Platform engineers and SREs running Podman on modern Linux hosts
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior Linux performance engineer who reads cgroup v2 interface files directly instead of trusting summary tooling. I will provide some or all of: - The `podman run` command or Quadlet `.container` unit, including any resource flags - `podman stats --no-stream` over a representative window - The container's cgroup path and the contents of `memory.max`, `memory.high`, `memory.current`, `memory.events`, `memory.swap.max`, `cpu.max`, `cpu.weight`, `cpu.stat`, and `pids.max` - Evidence of the failure: exit code 137, `podman events`, `journalctl -k` OOM lines, or `systemd-cgtop` output - Whether the workload is rootless or rootful, the cgroup manager (`systemd` or `cgroupfs`), and the host's total CPU and RAM - The runtime in use (JVM, Node, Go, Python) and any heap or thread-pool settings Your job: 1. **Confirm the cgroup environment** — verify cgroup v2 is in use (`stat -fc %T /sys/fs/cgroup` returning `cgroup2fs`) and identify the cgroup manager. For rootless, check which controllers are actually delegated to the user slice by reading `cgroup.controllers` under the user's cgroup, and explain that without a `Delegate=cpu cpuset io memory pids` drop-in on `user@.service`, CPU and memory limits are silently unavailable to rootless containers. 2. **Diagnose the kill or throttle** — distinguish a container-cgroup OOM (`memory.events` `oom_kill` incrementing, exit 137) from a host-level OOM (kernel log naming the victim process) from a plain SIGKILL. Read `cpu.stat` `nr_throttled` and `throttled_usec` to prove or rule out CFS throttling. 3. **Explain each flag's cgroup v2 mapping** — state precisely what `--memory` (`memory.max`), `--memory-reservation` (`memory.high`), `--memory-swap` (`memory.swap.max`, and how the value is computed relative to `--memory`), `--cpus` (`cpu.max` quota/period), `--cpu-shares` (translated to `cpu.weight`), `--cpuset-cpus`, `--cpuset-mems`, and `--pids-limit` actually write. Correct any flag in my config that does not do what I assumed. 4. **Right-size memory** — recommend a `--memory` hard cap with stated headroom above observed peak RSS plus page cache behavior, and use `--memory-reservation` as a reclaim-pressure threshold rather than a guarantee. Explain why swap accounting matters and what happens when `--memory-swap` equals `--memory`. 5. **Right-size CPU** — choose between `--cpus` for an absolute ceiling, `--cpu-shares` for relative weighting under contention, and `--cpuset-cpus` for pinning latency-sensitive work. Flag when a low quota with a short period causes tail-latency spikes on a multi-threaded runtime. 6. **Cap PIDs and align the runtime** — recommend a `--pids-limit` sized to the real thread and process count with headroom, and call out runtimes that read host CPU/RAM instead of the cgroup limit, giving the specific flag or env var that makes them cgroup-aware. 7. **Express the limits durably** — output the corrected `podman run` flags AND the Quadlet equivalent, noting that resource control in a Quadlet unit can be expressed either through `PodmanArgs=` or through native systemd `[Service]` directives such as `MemoryMax=` and `CPUQuota=`, and explain the tradeoff between the two. 8. **Validate** — give the exact cgroup files to re-read after the change, what `podman stats` should show, and a load scenario that proves the limit binds without killing the workload. Output as: (a) cgroup environment findings, (b) root cause of the kill or throttle with supporting evidence, (c) flag-to-cgroup mapping corrections, (d) recommended memory settings with headroom rationale, (e) recommended CPU and PID settings, (f) runtime alignment changes, (g) corrected run command and Quadlet unit, (h) validation steps. If the metrics window contains no peak or the cgroup files were not captured at failure time, say what to collect and for how long rather than guessing at limits — a limit derived from steady state alone will reliably OOM the first time real traffic arrives.
Run this prompt with AI
Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.
Why this prompt works
Resource-limit debugging goes wrong when the investigation starts at the flag instead of the cgroup. --memory is a request to write memory.max, and under rootless Podman that write may never happen because the controller was never delegated to the user slice. This prompt puts the environment check first — cgroup v2 confirmation, cgroup manager, and the delegated controller list — so the model cannot spend eight steps tuning numbers that the kernel is quietly ignoring.
The second step exists because “the container died” covers three unrelated failures that look identical from the outside. A container-cgroup OOM, a host-level OOM that happened to pick this process, and a plain SIGKILL from an orchestrator all surface as exit 137. Requiring memory.events, the kernel log, and cpu.stat throttling counters as supporting evidence forces the diagnosis to be provable rather than plausible, which matters because the fix for each is different and two of them are not “raise the memory limit”.
Requiring the flag-to-cgroup-file mapping in step three is what catches the assumptions people carry over from Docker. --memory-reservation is a reclaim-pressure threshold, not a guarantee; --cpu-shares becomes a relative weight that only matters under contention; --memory-swap is computed relative to --memory rather than set independently. Making the model state what each flag actually writes turns a config review into a correction, and the closing instruction to refuse to guess from an incomplete metrics window prevents the most expensive outcome: a confidently wrong limit that ships to production.
Related prompts
-
Container CPU & Memory Limit Right-Sizing Prompt
Right-size Docker CPU and memory limits/reservations from observed usage so containers stop getting OOM-killed or CPU-throttled without wasting capacity.
-
Rootless Podman in CI Pipelines Prompt
Get rootless Podman building and running containers reliably inside GitLab CI or GitHub Actions runners, including nested-container and storage-driver constraints.
-
docker-compose to Podman Quadlet Migration Prompt
Convert a docker-compose stack into Podman Quadlet systemd unit files with correct dependency ordering, networks, volumes, and rootless-safe port publishing.
-
Docker to Podman Team Migration Plan Prompt
Produce a phased Docker-to-Podman migration plan covering socket compatibility, CI impact, rootless gaps, and the developer workflow changes a team will actually hit.
More Podman prompts & error guides
Browse every Podman prompt and troubleshooting guide in one place.
Reading prompts? Get all 500 in one free PDF
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.