Skip to content
DevOps AI ToolKit
Newsletter
All prompts
AI for Kubernetes & Helm Difficulty: Advanced ClaudeChatGPTCursor

Kubernetes Memory QoS with cgroup v2 Tuning Prompt

Tune Memory QoS (memory.min / memory.high via cgroup v2) so latency-sensitive pods get protected reclaim guarantees and bursty pods are throttled before an OOM kill — instead of relying only on hard limits and reactive OOMKilled restarts.

Target user
Performance and reliability SREs tuning memory behavior on cgroup v2 nodes
Difficulty
Advanced
Tools
Claude, ChatGPT, Cursor

The prompt

You are a senior Kubernetes performance engineer who tunes memory behavior on cgroup v2 nodes. You understand the difference between the classic `requests`/`limits` model and the Memory QoS feature, which additionally sets `memory.min` and `memory.high` on the pod/container cgroup. You know how the kernel uses these — `memory.min` as protected (unreclaimable) memory, `memory.high` as a throttling threshold that triggers proactive reclaim before the hard `memory.max` OOM boundary.

I will provide:
- Node OS/kernel, cgroup version (must be v2), and container runtime
- Kubernetes version and whether the `MemoryQoS` feature is enabled
- The workload's QoS class (Guaranteed/Burstable/BestEffort), current requests/limits
- The symptom (OOMKills under burst, noisy-neighbor reclaim, latency spikes during memory pressure, throttling too aggressive)

Your job:

1. **Confirm applicability first**:
   - Verify the node is cgroup v2 (Memory QoS does nothing on v1) and the feature gate state for their version.
   - Confirm the runtime and kubelet expose the knobs; note it is opt-in and version-dependent.

2. **Explain what Memory QoS actually sets** and how it maps from the pod spec:
   - `memory.min` derived from `requests.memory` → memory the kernel will not reclaim from the container (protection).
   - `memory.high` derived from limits and the kubelet's throttling factor → the soft threshold where the kernel throttles the workload and reclaims proactively, *before* hitting `memory.max`.
   - `memory.max` = `limits.memory` → the hard OOM boundary (unchanged behavior).
   - How QoS class changes which of these are set (Guaranteed vs Burstable vs BestEffort).

3. **Map the symptom to a fix**:
   - **OOMKills under burst** → the app blows past `memory.max` with no soft warning; Memory QoS `memory.high` gives the kernel a chance to reclaim/throttle first. Also revisit limit sizing.
   - **Noisy neighbor stealing reclaim** → set `requests.memory` accurately so `memory.min` protects the victim's working set.
   - **Throttling too aggressive (latency spikes)** → the throttling factor is pulling `memory.high` too close to usage; adjust requests/limits or the factor.

4. **Produce concrete guidance**:
   - The exact requests/limits changes and, where relevant, the kubelet `memoryThrottlingFactor` implication.
   - The QoS class you should target and why.
   - Node-level verification commands reading the actual cgroup files.

5. **Trade-offs and interactions**:
   - Memory QoS is protection + graceful throttling, not a substitute for correct limits.
   - Interaction with node `MemoryPressure` eviction, `swap` (NodeSwap) if enabled, and the OOM killer.
   - Why `memory.high` throttling can *increase* latency for a memory-hungry app (reclaim CPU cost) — a deliberate trade of throughput for stability.

6. **Rollout & rollback**: canary on a labeled node pool, what metrics to watch (working set, throttling events, OOM rate), and how to revert.

Mark DESTRUCTIVE / footgun: enabling Memory QoS expecting it to "fix" undersized limits (it does not raise `memory.max`), setting `requests.memory` far above real usage (wastes protected memory and hurts bin-packing), and assuming behavior on cgroup v1 nodes (the feature is a no-op there).

---

Node OS / kernel / cgroup version / runtime: [DESCRIBE]
Kubernetes version + MemoryQoS gate state: [DESCRIBE]
Workload QoS class + requests/limits:
```yaml
[PASTE resources block]
```
Symptom (OOMKills / noisy neighbor / latency / over-throttling): [DESCRIBE]

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

Most memory incidents get “fixed” by bumping limits.memory until the OOMKills stop — which just moves the cliff. Memory QoS adds a guardrail (memory.high) and a floor (memory.min) so the kernel throttles and protects before the hard OOM. This prompt makes the assistant confirm cgroup v2, map your specific symptom to the right knob, and be explicit that QoS is not a substitute for correct limits.

How to use it

  1. Verify cgroup v2 up front — everything below is inert on v1.
  2. Bring real numbers: observed working set, OOM frequency, current requests/limits.
  3. State your SLO so the throughput-vs-stability trade of memory.high throttling can be judged.

Useful commands

# Is the node on cgroup v2?
stat -fc %T /sys/fs/cgroup        # cgroup2fs = v2, tmpfs = v1

# Read the actual QoS knobs for a container cgroup (path varies by runtime/QoS class)
POD_CG=/sys/fs/cgroup/kubepods.slice/kubepods-burstable.slice/<pod-uid-slice>
cat $POD_CG/memory.min $POD_CG/memory.high $POD_CG/memory.max
cat $POD_CG/memory.current
cat $POD_CG/memory.events          # 'high' and 'oom' counters

# Kubelet-side: confirm the feature and throttling factor
ps aux | grep kubelet | tr ',' '\n' | grep -iE 'MemoryQoS|memoryThrottlingFactor'

# Workload view
kubectl get pod <pod> -o jsonpath='{.status.qosClass}{"\n"}'
kubectl describe pod <pod> | grep -A3 'Limits\|Requests'

Pattern: latency-sensitive Burstable pod with protection

apiVersion: v1
kind: Pod
metadata:
  name: latency-svc
spec:
  containers:
  - name: svc
    image: myorg/svc:v2
    resources:
      requests:
        memory: "512Mi"        # -> memory.min: protect the real working set from reclaim
        cpu: "250m"
      limits:
        memory: "1Gi"          # -> memory.max (hard OOM). memory.high sits below this
                               #    via the kubelet throttling factor, giving proactive reclaim

Common findings this catches

  • Sudden OOMKills with no warningmemory.high was never set (v1 node or feature off); enable Memory QoS and revisit limits.
  • Victim pod losing its cache to a noisy neighborrequests.memory too low, so memory.min under-protects; size it to the working set.
  • Latency spikes under pressure → throttling factor pulls memory.high too close to usage; widen the gap or accept the trade.
  • “We enabled Memory QoS but still OOM” → limits are simply too small; QoS never raises memory.max.
  • Inconsistent behavior across nodes → mixed cgroup v1/v2 or feature-gate drift in the node pool.

When to escalate

  • Node pool still on cgroup v1 — coordinate an OS/kernel migration before relying on Memory QoS.
  • Persistent OOM after tuning — the workload is genuinely under-provisioned or leaking; profile the app.
  • Swap-enabled nodes with unexpected reclaim — re-evaluate MemoryPressure eviction thresholds with the node team.

Related prompts

More Kubernetes & Helm prompts & error guides

Browse every Kubernetes & Helm prompt and troubleshooting guide in one place.

Free download · 368-page PDF

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.