How to fix MemoryPressure in Kubernetes

KubernetesINTERMEDIATEHIGHUpdated Dec 5, 2025· 150 views

MemoryPressure indicates a node is running critically low on available memory. The kubelet responds by tainting the node, stopping new pod scheduling, and evicting lower-priority pods to reclaim memory.

Quick fix

Fixes MemoryPressure

kubectl describe node <NODE_NAME>
  1. Verify MemoryPressure condition on the node
  2. Check actual memory usage on the node
  3. Identify pods to evict or remove
  4. Configure proper eviction thresholds
kubernetes — error
kubectl describe node <NODE_NAME>
MemoryPressure

What this error means

MemoryPressure is a node condition that indicates a Kubernetes node is running critically low on available memory. When the kubelet detects that available memory has dropped below its configured eviction threshold, it sets the MemoryPressure condition to True and applies the node.kubernetes.io/memory-pressure:NoSchedule taint to prevent new pods from being scheduled on that node. This condition triggers the kubelet's node-pressure eviction mechanism, which proactively terminates pods on the node to reclaim memory and prevent a system-level Out-Of-Memory (OOM) killer from becoming involved. The kubelet monitors memory continuously via cAdvisor and makes eviction decisions based on pod QoS class (Guaranteed, Burstable, or BestEffort), with BestEffort pods being evicted first. MemoryPressure can arise from legitimate high workloads, but often indicates resource overcommitment, memory leaks in applications, or insufficient node capacity for the scheduled pods. If eviction cannot reclaim memory quickly enough, the Linux kernel's OOM killer may still be invoked.

Typical symptoms

  • Node shows MemoryPressure=True in "kubectl describe node" output
  • Pods with BestEffort QoS class are being evicted with reason "The node was low on resource: memory"
  • New pods fail to schedule on the affected node and remain Pending
  • Applications crash with OOMKilled status (exit code 137) despite no explicit memory limit being set
  • Container memory usage gradually increases until pods are terminated, then restarts (memory leak pattern)
  • "kubectl top nodes" shows memory usage approaching or exceeding node capacity

Common causes

  1. Too many pods scheduled on a single node exceeding its physical memory capacity (resource overcommitment)
  2. Memory leaks in containerized applications that cause gradual memory consumption over time
  3. Pod resource requests are too low relative to actual runtime memory consumption
  4. System daemons and kubelet reserved memory not properly accounted for via --system-reserved and --kubelet-reserved flags
  5. Bursty workloads with sudden memory spikes exceeding available memory between kubelet polling intervals
  6. Incorrect eviction threshold configuration allowing memory to drop below system stability requirements
  7. Cgroup memory limits not properly enforced due to kernel version mismatch

How to fix "MemoryPressure"

1Verify MemoryPressure condition on the node

Confirm the node is actually under memory pressure:

bash
kubectl describe node <NODE_NAME>

Look for the Conditions section and check if MemoryPressure=True. Also inspect the Taints section to see if node.kubernetes.io/memory-pressure:NoSchedule is present.

2Check actual memory usage on the node

Examine current memory consumption to understand the scope:

bash
# View node resource usage
kubectl top nodes

# View pod memory usage on specific node
kubectl top pods --all-namespaces --sort-by=memory

# SSH into node and check kernel's view of memory
kubectl debug node/<NODE_NAME> -it --image=ubuntu
# Inside debug container:
cat /proc/meminfo
free -h

Note: 'kubectl top' uses kubelet cgroup stats (the authoritative source), while 'free -h' may show different values.

3Identify pods to evict or remove

Review pods on the affected node and identify which can be safely removed:

bash
# List all pods on specific node
kubectl get pods --all-namespaces --field-selector spec.nodeName=<NODE_NAME>

# Check pod resource requests/limits
kubectl describe pod <POD_NAME> -n <NAMESPACE> | grep -A 5 'Limits\|Requests'

# Identify BestEffort pods (no resource requests/limits - evicted first)
kubectl get pods --all-namespaces -o custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace,QOS:.status.qosClass --field-selector spec.nodeName=<NODE_NAME>

Pods with BestEffort QoS will be evicted first. Consider scaling down non-critical workloads.

4Configure proper eviction thresholds

Set kubelet eviction thresholds to reclaim memory before the system OOM killer engages. Edit the kubelet configuration:

yaml
# In /etc/kubernetes/kubelet-config.yaml
evictionHard:
  memory.available: "500Mi"
evictionSoft:
  memory.available: "1.5Gi"
evictionSoftGracePeriod:
  memory.available: "1m30s"
systemReserved:
  memory: "1.5Gi"
kubeletReserved:
  memory: "100Mi"

Restart the kubelet after changes. Set soft thresholds ~20-30% above hard thresholds to give time for graceful eviction.

5Set appropriate resource requests and limits

Ensure pods declare realistic resource requests/limits:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: my-app:1.0
    resources:
      requests:
        memory: "256Mi"
      limits:
        memory: "512Mi"

Run your application under load to measure realistic memory usage, then set requests to ~80% of peak observed usage. Consider using Vertical Pod Autoscaler (VPA) to analyze historical usage.

6Add more memory or scale the cluster

If memory pressure is persistent despite tuning, increase cluster capacity:

bash
# Scale up node pool (cloud provider specific)
# GKE example:
gcloud container node-pools update <POOL_NAME> \
  --machine-type n1-standard-4 \
  --cluster <CLUSTER_NAME>

Alternatively, distribute pods across more nodes using pod anti-affinity:

yaml
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - my-app
        topologyKey: kubernetes.io/hostname

Advanced notes

The kubelet's node-pressure eviction mechanism is designed to prevent system-level OOM events by proactively terminating pods. However, if memory spikes faster than the kubelet can detect it (cAdvisor polls at intervals, default ~10s), the kernel OOM killer may still be invoked. Enable --kernel-memcg-notification for immediate memcg notifications.

The kubelet respects QoS classes when evicting pods: BestEffort pods are evicted first, followed by Burstable pods, then Guaranteed pods. Non-BestEffort pods receive a toleration for the memory-pressure taint by default.

Hard eviction thresholds use a 0-second termination grace period (immediate kill), while soft thresholds respect eviction-max-pod-grace-period (default 30s). The kubelet does NOT respect PodDisruptionBudgets during eviction—pods are evicted regardless of budget constraints.

The kubelet calculates memory.available from cgroup stats, not from host-level tools. This can show different values than free -m because the kubelet excludes inactive_file (reclaimable file cache).

Frequently asked questions

What does "MemoryPressure" mean?
MemoryPressure is a node condition that indicates a Kubernetes node is running critically low on available memory. io/memory-pressure:NoSchedule taint to prevent new pods from being scheduled on that node. This condition triggers the kubelet's node-pressure eviction mechanism, which proactively terminates pods on the node to reclaim memory and prevent a system-level Out-Of-Memory (OOM) killer from becoming involved.
How do I fix "MemoryPressure"?
MemoryPressure indicates a node is running critically low on available memory. The kubelet responds by tainting the node, stopping new pod scheduling, and evicting lower-priority pods to reclaim memory.
What causes "MemoryPressure"?
Too many pods scheduled on a single node exceeding its physical memory capacity (resource overcommitment) Memory leaks in containerized applications that cause gradual memory consumption over time Pod resource requests are too low relative to actual runtime memory consumption
Is the "MemoryPressure" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading