How to fix CPU limits exceeded, container throttled in Kubernetes

KubernetesINTERMEDIATEMEDIUMUpdated Dec 6, 2025· 219 views

Pod CPU limits cause the kernel to throttle container processes when they exceed configured limits. Unlike memory, throttled pods continue running but with reduced performance. Fix by adjusting CPU requests/limits, enabling HPA, or removing inappropriate limits.

Quick fix

Fixes CPU_THROTTLE

# Check pod resource usage:
kubectl top pod -n <namespace> <pod-name>

# View current limits:
kubectl describe pod -n <namespace> <pod-name> | grep -A 4 "Limits\|Requests"

# Check throttling metrics in Prometheus:
container_cpu_cfs_throttled_seconds_total
container_cpu_cfs_throttled_periods_total
  1. Monitor CPU usage and throttling
  2. Establish baseline CPU usage
  3. Increase CPU limits temporarily (short-term fix)
  4. Configure CPU requests properly
kubernetes — error
# Check pod resource usage:
kubectl top pod -n <namespace> <pod-name>
# View current limits:
kubectl describe pod -n <namespace> <pod-name> | grep -A 4 "Limits\|Requests"
# Check throttling metrics in Prometheus:
container_cpu_cfs_throttled_seconds_total
container_cpu_cfs_throttled_periods_total
CPU limits exceeded, container throttled

What this error means

When a Kubernetes pod specifies a CPU limit, the Linux CFS (Completely Fair Scheduler) kernel subsystem enforces that limit by throttling—slowing down the container's processes to prevent exceeding the allocated CPU percentage. Unlike memory limits, which kill pods that exceed them, CPU throttling just reduces throughput and increases latency. The container keeps running but at reduced performance, causing: - Increased API response times - Timeout failures - Queue backlogs - Cascading failures in dependent services CPU throttling becomes obvious when comparing actual CPU usage (from metrics) versus the container's performance degradation.

Typical symptoms

  • Sudden spike in API response times despite sufficient traffic
  • Application timeouts that seem random or intermittent
  • Database queries taking 10x longer than normal
  • Prometheus metric container_cpu_cfs_throttled_seconds_total increasing rapidly
  • Pod staying Running but severely degraded performance
  • Batch jobs taking much longer than expected
  • Tail latency (p99, p95) dramatically increasing

Common causes

  1. CPU limit set too low for the application's workload
  2. Burst traffic exceeding the average CPU request
  3. CPU request lower than typical baseline usage
  4. Noisy neighbor pod consuming shared CPU on the node
  5. Multiple pods on same node competing for limited CPU
  6. Application has hidden multi-threading or async work
  7. Lack of Horizontal Pod Autoscaling (HPA) for CPU-bound workloads

How to fix "CPU limits exceeded, container throttled"

1Monitor CPU usage and throttling

Identify if throttling is actually happening:

bash
# Check pod resource usage:
kubectl top pod -n <namespace> <pod-name>

# View current limits:
kubectl describe pod -n <namespace> <pod-name> | grep -A 4 "Limits\|Requests"

# Check throttling metrics in Prometheus:
container_cpu_cfs_throttled_seconds_total
container_cpu_cfs_throttled_periods_total

Compare the pod's actual CPU usage against its limit.

2Establish baseline CPU usage

Determine what CPU your application actually needs:

bash
# Monitor during typical load:
kubectl top pod -n <namespace> <pod-name> --containers

# Track over time using Prometheus:
rate(container_cpu_usage_seconds_total[5m])

# Check 95th percentile usage:
histogram_quantile(0.95, rate(container_cpu_usage_seconds_total[5m]))

Use this data to set appropriate requests and limits.

3Increase CPU limits temporarily (short-term fix)

Edit the deployment to increase CPU limits:

bash
kubectl edit deployment -n <namespace> <deployment-name>

Update the limits:

yaml
resources:
  limits:
    cpu: "2"      # Increase from current limit
  requests:
    cpu: "1"      # Set to your baseline

New pods will respect the updated limits:

bash
kubectl rollout restart deployment -n <namespace> <deployment-name>
4Configure CPU requests properly

Best practice is to set requests equal to or slightly above peak usage, and limits higher for burst traffic:

yaml
resources:
  requests:
    cpu: "500m"      # What pod consistently needs
  limits:
    cpu: "1000m"     # Max burst capacity

The difference between request and limit allows for temporary spikes without throttling.

5Enable Horizontal Pod Autoscaling (HPA)

Scale pods based on CPU usage instead of trying to give each pod unlimited CPU:

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

When CPU usage exceeds 70%, Kubernetes adds more pod replicas.

6Optimize application code

Review the application for inefficiencies:

- Profile CPU usage: perf, py-spy, pprof
- Check for infinite loops or busy-wait patterns
- Reduce unnecessary computations in request paths
- Use caching (Redis, memcached) to avoid repeated work
- Batch operations to reduce per-request overhead
- Use async/await patterns for I/O-bound work

Example with pprof (Go):

go
import _ "net/http/pprof"

// Then visit http://localhost:6060/debug/pprof/
7Validate the fix

After making changes, monitor performance:

bash
# Watch real-time pod CPU:
kubectl top pod -n <namespace> -w

# Check metrics over longer periods:
# - API response times (p50, p95, p99)
# - Error rates
# - Throughput (requests/second)

# Verify throttling has stopped:
# (throttled_seconds should stop increasing)
container_cpu_cfs_throttled_seconds_total

Performance should normalize within minutes.

8Implement long-term monitoring

Set up alerts to prevent future throttling:

yaml
# Prometheus alert:
- alert: PodCPUThrottling
  expr: |
    rate(container_cpu_cfs_throttled_seconds_total[5m]) > 0.1
  for: 5m
  annotations:
    summary: "Pod {{ $labels.pod_name }} is being throttled"

Monitor in Grafana:
- Graph: rate(container_cpu_cfs_throttled_seconds_total[5m])
- Set threshold alert at 10% throttling rate

Advanced notes

### Understanding CFS Throttling

The Linux CFS scheduler divides CPU time into periods (default 100ms). When a container reaches its limit within a period, the kernel throttles it until the next period starts. This is why latency becomes unpredictable—requests that cross period boundaries experience severe delays.

### CPU Requests vs Limits

- Request: Guaranteed minimum CPU (used by scheduler for pod placement)
- Limit: Hard ceiling on CPU usage (enforced by kernel throttling)

Setting request=limit removes burst capacity. Better practice:
- request = 80th percentile of your usage
- limit = 95th percentile or 2x request

### QoS Classes

Kubernetes assigns QoS based on requests/limits:
- Guaranteed: request == limit (protected from eviction)
- Burstable: request < limit (can be evicted under pressure)
- BestEffort: no request or limit (evicted first)

### Removing CPU Limits

Some organizations remove CPU limits entirely to avoid throttling:

yaml
resources:
  requests:
    cpu: "500m"
  # No limits - pod can burst up to node's CPU

Only safe if you have:
- Good node resource monitoring
- Pod Disruption Budgets configured
- Sufficient cluster headroom

### Multi-core Applications

Applications using multiple threads/processes should request multiple CPU:

yaml
resources:
  requests:
    cpu: "4"    # 4 cores
  limits:
    cpu: "8"    # Burst to 8 cores

### Metric Interpretation

- High throttled_seconds = significant CPU contention
- Throttled_periods < throttled_seconds indicates severe throttling
- Zero throttling with low usage = limits set too high

### Alternative: Remove Limits Entirely

For non-noisy-neighbor environments:

yaml
resources:
  requests:
    cpu: "1"
  # limits: omitted - no throttling

Frequently asked questions

What does "CPU_THROTTLE" mean?
When a Kubernetes pod specifies a CPU limit, the Linux CFS (Completely Fair Scheduler) kernel subsystem enforces that limit by throttling—slowing down the container's processes to prevent exceeding the allocated CPU percentage. Unlike memory limits, which kill pods that exceed them, CPU throttling just reduces throughput and increases latency. The container keeps running but at reduced performance, causing: - Increased API response times - Timeout failures - Queue backlogs - Cascading failures in dependent services CPU throttling becomes obvious when comparing actual CPU usage (from metrics) versus the container's performance degradation.
How do I fix "CPU_THROTTLE"?
Pod CPU limits cause the kernel to throttle container processes when they exceed configured limits. Unlike memory, throttled pods continue running but with reduced performance. Fix by adjusting CPU requests/limits, enabling HPA, or removing inappropriate limits.
What causes "CPU_THROTTLE"?
CPU limit set too low for the application's workload Burst traffic exceeding the average CPU request CPU request lower than typical baseline usage
Is the "CPU_THROTTLE" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading