How to fix CPU resource exceeded in Kubernetes

KubernetesINTERMEDIATEMEDIUMUpdated Dec 6, 2025· 188 views

The "CPU resource exceeded" error occurs when a pod uses more CPU than its limit. Kubernetes throttles CPU-limited containers, causing performance degradation and timeouts. This prevents a single pod from consuming all node CPU but requires proper limit configuration.

Quick fix

Fixes CPU resource exceeded

# View current CPU usage vs limits:
kubectl top pods -A

# Detailed resource metrics:
kubectl describe pod <pod-name> -n <namespace>

# Check cgroup CPU metrics directly (requires node access):
ssh <node-ip>
cat /sys/fs/cgroup/cpuacct/kubepods.slice/kubepods-pod<uid>/cpuacct.usage_percpu_sys
cat /sys/fs/cgroup/cpu/kubepods.slice/kubepods-pod<uid>/cpu.stat  # Shows throttle info
  1. Identify CPU throttling using metrics
  2. Monitor CPU usage patterns over time
  3. Review the pod CPU request and limit
  4. Increase CPU limit gradually
kubernetes — error
# View current CPU usage vs limits:
kubectl top pods -A
# Detailed resource metrics:
kubectl describe pod <pod-name> -n <namespace>
# Check cgroup CPU metrics directly (requires node access):
ssh <node-ip>
cat /sys/fs/cgroup/cpuacct/kubepods.slice/kubepods-pod<uid>/cpuacct.usage_percpu_sys
cat /sys/fs/cgroup/cpu/kubepods.slice/kubepods-pod<uid>/cpu.stat # Shows throttle info
CPU resource exceeded

What this error means

Kubernetes enforces CPU limits using Linux cgroups. Unlike memory limits which result in OOMKill, CPU limits don't terminate pods—instead they throttle the CPU time available to the container. When a pod exceeds its CPU limit, the Linux kernel restricts its CPU access, causing increased latency and timeouts. CPU is a compressible resource (can be throttled without killing the process), while memory is incompressible (exceeding limits kills the pod). CPU throttling happens silently; pods continue running but perform poorly.

Typical symptoms

  • Application responds slowly despite low load on other nodes
  • Database queries timeout despite fast execution elsewhere
  • HTTP requests hang intermittently with no error messages
  • kubectl top pods shows CPU near the limit (e.g., 498m of 500m)
  • Logs show "context deadline exceeded" or "i/o timeout" errors
  • Metrics show high CPU throttle rate (cgroup throttling)
  • Performance degrades consistently under load

Common causes

  1. Pod CPU limit set too low for the workload's normal operating range
  2. Legitimate traffic spike causing temporary CPU spike beyond limit
  3. Code change introducing more CPU-intensive operations (loops, calculations)
  4. Missing or underestimated CPU request causing oversubscription
  5. Noisy neighbor: another pod on the same node consuming CPU
  6. Inefficient algorithm or N+1 queries causing excessive CPU usage
  7. JVM or runtime startup overhead exceeding limit during initialization

How to fix "CPU resource exceeded"

1Identify CPU throttling using metrics

Check if the pod is being throttled:

bash
# View current CPU usage vs limits:
kubectl top pods -A

# Detailed resource metrics:
kubectl describe pod <pod-name> -n <namespace>

# Check cgroup CPU metrics directly (requires node access):
ssh <node-ip>
cat /sys/fs/cgroup/cpuacct/kubepods.slice/kubepods-pod<uid>/cpuacct.usage_percpu_sys
cat /sys/fs/cgroup/cpu/kubepods.slice/kubepods-pod<uid>/cpu.stat  # Shows throttle info

If throttle count is increasing, the pod is being rate-limited.

2Monitor CPU usage patterns over time

Use Prometheus or kubectl to observe CPU behavior:

bash
# If using Prometheus:
kubectl port-forward -n prometheus svc/prometheus 9090:9090
# Query: rate(container_cpu_usage_seconds_total{pod_name="<pod>"}[5m])

# Watch CPU usage in real-time:
kubectl top pods <pod-name> -n <namespace> --containers -w

# Get historical data:
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/<ns>/pods/<pod>/cpu_usage

Identify peak usage: Does it consistently exceed the limit, or only under high load?

3Review the pod CPU request and limit

Check current configuration:

bash
kubectl get pod <pod-name> -n <namespace> -o yaml | grep -A 10 "resources:"

# Or describe:
kubectl describe pod <pod-name> -n <namespace> | grep -A 5 "Limits\|Requests"

Example output:

bash
Limits:
  cpu: 500m  # 0.5 cores
Requests:
  cpu: 250m

The limit is the hard cap; the pod cannot exceed this.

4Increase CPU limit gradually

Update the pod/deployment with a higher CPU limit:

bash
# For a deployment:
kubectl set resources deployment <name> -n <namespace> --limits=cpu=1  # 1 core

# Or patch directly:
kubectl patch deployment <name> -n <namespace> -p '{"spec":{"template":{"spec":{"containers":[{"name":"<container>","resources":{"limits":{"cpu":"1"}}}]}}}}'

# Or edit the YAML:
kubectl edit deployment <name> -n <namespace>
# Change: limits.cpu from 500m to 1000m (1 core)
kubectl apply -f deployment.yaml

Increase incrementally: 500m → 1000m → 2000m until performance improves.

5Optimize the application code for CPU efficiency

Reduce CPU consumption rather than just increasing limits:

Java applications:

bash
# Check for hot CPU usage:
java -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions myapp.jar

# Reduce GC overhead:
-XX:+UseG1GC -XX:MaxGCPauseMillis=200

Python/Node.js:

python
# Profile CPU usage:
import cProfile
cProfile.run('myfunction()')

# Or use async/await for I/O-bound operations:
async def fetch():
    await asyncio.gather(*[requests.get(url) for url in urls])

Common optimizations:
- Replace N+1 queries with batch/join queries
- Cache expensive computations
- Use async/non-blocking I/O
- Remove unnecessary loops or recursive calls

6Adjust CPU request to prevent oversubscription

Set request to a realistic baseline CPU need:

bash
kubectl set resources deployment <name> -n <namespace> --requests=cpu=500m

# Or edit:
kubectl edit deployment <name> -n <namespace>

Guideline:
- Request: 80% of peak normal usage
- Limit: 150% of request (allows temporary spikes)

Example:

yaml
resources:
  requests:
    cpu: 200m      # 200 millicores
  limits:
    cpu: 500m      # 500 millicores

Requests are used for scheduling; limits are hard caps.

7Check for noisy neighbors on the node

Identify if other pods are consuming excessive CPU:

bash
# List pods on the same node sorted by CPU:
kubectl get pods -A --field-selector=spec.nodeName=<node> --sort-by=.status.containerStatuses[0].lastState.terminated.reason

# Top pods by CPU:
kubectl top pods -A --sort-by=cpu

# Check node CPU allocation:
kubectl describe node <node-name> | grep -A 10 "Allocated resources"

If other pods are using significant CPU, move your pod to a less loaded node:

bash
kubectl cordon <busy-node>  # Prevent new pods from scheduling
kubectl drain <busy-node> --ignore-daemonsets  # Gracefully move existing pods
8Use Kubernetes QoS classes for priority

Set proper QoS to help the scheduler make better decisions:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: high-priority-app
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        resources:
          requests:
            cpu: 1
            memory: 512Mi
          limits:
            cpu: 2
            memory: 1Gi
      priorityClassName: high-priority  # Optional

QoS classes:
- Guaranteed: requests == limits (never evicted for resource pressure)
- Burstable: requests < limits (evicted if node has pressure)
- BestEffort: no requests/limits (evicted first)

Use Guaranteed for critical apps to prevent eviction during CPU throttling.

Advanced notes

CPU throttling is subtle—unlike OOMKill which causes obvious failures, throttled pods continue running with degraded performance. Monitor throttle metrics: container_cpu_cfs_throttled_seconds_total and container_cpu_cfs_throttled_periods_total. A good rule of thumb: request 50-70% of expected peak load, limit at 100-150% of request. Avoid setting very high limits (cores); use autoscaling instead. For latency-sensitive applications (APIs, databases), consider pod disruption budgets and node affinity to prevent contention. CPU limits are enforced at 100ms granularity (CFS period), so very short-duration spikes may slip through. Kubernetes v1.26+ supports CPU OverCommit to reduce resource waste. Java applications particularly struggle with CPU limits due to GC overhead—ensure adequate limits (500m minimum) for Java services.

Frequently asked questions

What does "CPU resource exceeded" mean?
Kubernetes enforces CPU limits using Linux cgroups. Unlike memory limits which result in OOMKill, CPU limits don't terminate pods—instead they throttle the CPU time available to the container. When a pod exceeds its CPU limit, the Linux kernel restricts its CPU access, causing increased latency and timeouts.
How do I fix "CPU resource exceeded"?
The "CPU resource exceeded" error occurs when a pod uses more CPU than its limit. Kubernetes throttles CPU-limited containers, causing performance degradation and timeouts. This prevents a single pod from consuming all node CPU but requires proper limit configuration.
What causes "CPU resource exceeded"?
Pod CPU limit set too low for the workload's normal operating range Legitimate traffic spike causing temporary CPU spike beyond limit Code change introducing more CPU-intensive operations (loops, calculations)
Is the "CPU resource exceeded" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading