3.6 Resource Requests, Limits & Namespace ResourceQuotas

Key Takeaways

  • Resource Requests represent guaranteed compute capacity used by kube-scheduler for Pod placement; Limits represent hard ceilings enforced by Linux cgroups at runtime.
  • CPU is a compressible resource subject to CFS bandwidth throttling when limits are exceeded; Memory is incompressible and triggers OOM Killer (exit code 137) upon breach.
  • Kubernetes assigns Guaranteed, Burstable, or BestEffort QoS from requests and limits; node-pressure eviction ranks Pods by usage above requests, Pod Priority, and relative excess usage rather than a fixed QoS ladder.
  • LimitRanges define default, minimum, and maximum resource allocations per container/pod within a namespace, automatically injecting defaults if requests are omitted.
  • ResourceQuotas enforce aggregate namespace-wide caps on compute resources (CPU/memory), storage requests, and object counts (Pods, Services, Secrets).
Last updated: August 2026

Resource Requests, Limits & Namespace ResourceQuotas

In multi-tenant Kubernetes clusters, uncontrolled workloads can monopolize CPU and memory, causing noisy neighbor problems, performance degradation, and node starvation. Kubernetes provides a robust, multi-tiered resource governance model: Requests and Limits at the container level, Quality of Service (QoS) classes at the Pod level, and LimitRanges and ResourceQuotas at the namespace level.


1. Requests vs Limits: Scheduling and Runtime Enforcement

Understanding the precise mechanical distinction between resource requests and resource limits is fundamental to Kubernetes operations and CKA exam success.

+-----------------------------------------------------------------------------------------+
|                           REQUESTS VS LIMITS MECHANICS                                  |
|                                                                                         |
|   +---------------------------------------+   +-------------------------------------+   |
|   |         RESOURCE REQUESTS             |   |           RESOURCE LIMITS           |   |
|   |  - Used by: kube-scheduler            |   |  - Enforced by: Linux cgroups       |   |
|   |  - Role: Guaranteed minimum allocation|   |  - Role: Hard maximum threshold     |   |
|   |  - Node selection: Capacity >= Sum(Req|   |  - Exceeding CPU: Throttling (CFS)  |   |
|   +---------------------------------------+   |  - Exceeding Memory: OOMKilled (137)|   |
|                                               +-------------------------------------+   |
+-----------------------------------------------------------------------------------------+

CPU Resources (Compressible)

  • Units: Measured in millicores (m) or whole cores (1000m = 1 vCPU / Core / Hyperthread). A request of 250m represents 25% of a CPU core.
  • Behavior Under Contention: CPU is a compressible resource. If a container attempts to consume more CPU than its allocated limit, the Linux kernel Completely Fair Scheduler (CFS) throttles the container by restricting its CPU execution time slices (using cpu.cfs_quota_us and cpu.cfs_period_us in cgroups v1, or cpu.max in cgroups v2). The container experiences latency and reduced processing throughput, but the process is never killed.

Memory Resources (Incompressible)

  • Units: Measured in bytes or power-of-two mebibytes/gibibytes (Mi, Gi) or decimal megabytes/gigabytes (M, G). 1Mi = 1,048,576 bytes, whereas 1M = 1,000,000 bytes.
  • Behavior Under Contention: Memory is an incompressible resource. If a container consumes all its allocated memory and attempts to allocate more beyond its limits.memory, the Linux kernel triggers the Out Of Memory (OOM) Killer. The kernel immediately sends a SIGKILL (Signal 9) to the container process, terminating it with Exit Code 137 (128 + 9). kubectl describe pod will display Reason: OOMKilled.

Ephemeral Storage Requests and Limits

Kubernetes also supports tracking local node storage (including container writable layers, container logs in /var/log/pods, and emptyDir volumes):

  • requests.ephemeral-storage: Informs the scheduler of minimum disk capacity needed on the node.
  • limits.ephemeral-storage: Hard cap. If an emptyDir volume or container writable layer exceeds this limit, the kubelet evicts the Pod from the node.
apiVersion: v1
kind: Pod
metadata:
  name: backend-processor
  namespace: production
spec:
  containers:
    - name: app
      image: redis:7.0-alpine
      resources:
        requests:
          cpu: "250m"
          memory: "512Mi"
          ephemeral-storage: "1Gi"
        limits:
          cpu: "1000m"
          memory: "1Gi"
          ephemeral-storage: "2Gi"

2. Quality of Service (QoS) Classification

The kube-scheduler and kubelet automatically assign every Pod to one of three Quality of Service (QoS) classes based entirely on how requests and limits are configured across all containers in the Pod:

+-----------------------------------------------------------------------------------------+
|                            QOS DETERMINATION MATRIX                                     |
|                                                                                         |
|   1. GUARANTEED (Highest Priority | oom_score_adj: -997)                                |
|      - Every container in Pod has CPU & Memory Requests AND Limits defined.             |
|      - CPU Request == CPU Limit AND Memory Request == Memory Limit for all containers.  |
|                                                                                         |
|   2. BURSTABLE (Moderate Priority | oom_score_adj: 100 - 999)                           |
|      - At least one container has a CPU or Memory Request.                              |
|      - Does not meet the strict equality criteria of Guaranteed.                        |
|                                                                                         |
|   3. BESTEFFORT (Lowest Priority | oom_score_adj: 1000)                                 |
|      - No Requests and no Limits set for ANY container in the Pod.                      |
+-----------------------------------------------------------------------------------------+
QoS ClassQualification RequirementTypical memory OOM adjustment
GuaranteedEvery container specifies CPU and memory requests and limits, with each request equal to its limit.Strong protection (commonly -997)
BurstableAt least one container has a request or limit, but the Pod does not qualify as Guaranteed.Calculated from requested memory
BestEffortNo container has CPU or memory requests or limits.Least protection (commonly 1000)

The OOM adjustment affects the Linux kernel OOM killer. Kubelet node-pressure eviction is a separate ranking process. For a resource such as memory, kubelet first separates Pods whose current usage exceeds their requests from those that do not. Within the relevant group it considers Pod Priority, then how far usage exceeds the request. A BestEffort Pod has a zero request and commonly ranks as exceeding it, but a fixed “BestEffort, then Burstable, then Guaranteed” ordering is not guaranteed. A high-priority BestEffort Pod can outlive a lower-priority Burstable Pod that is also over request.

Pods whose usage is below requests are not immune if kubelet cannot reclaim enough resource. Static Pods and system-critical workloads also have priority considerations. Diagnose actual decisions through node events and kubelet logs rather than inferring solely from the displayed QoS class.


3. LimitRanges---

3. LimitRanges: Namespace Defaulting and Boundaries

A LimitRange is a namespaced resource that automatically injects default requests/limits into incoming Pods and enforces boundary constraints (min/max size).

apiVersion: v1
kind: LimitRange
metadata:
  name: core-resource-limits
  namespace: staging
spec:
  limits:
    - type: Container
      default:            # Default LIMIT if omitted by user
        cpu: "500m"
        memory: "512Mi"
      defaultRequest:     # Default REQUEST if omitted by user
        cpu: "100m"
        memory: "256Mi"
      max:                # Maximum allowed request/limit per container
        cpu: "2000m"
        memory: "2Gi"
      min:                # Minimum allowed request/limit per container
        cpu: "50m"
        memory: "64Mi"
      maxLimitRequestRatio:
        cpu: "4"          # Limit cannot exceed 4x the Request
    - type: Pod
      max:
        cpu: "4000m"
        memory: "4Gi"

[!NOTE] If a developer applies a Pod manifest with no resources block in a namespace with an active LimitRange, the Admission Controller automatically mutates the Pod manifest, populating it with the defaultRequest and default limit values.


4. ResourceQuotas: Namespace Capacity Caps

A ResourceQuota restricts total aggregate resource consumption across an entire namespace, preventing any single team or project from consuming all cluster compute, storage, or object counts.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-compute-quota
  namespace: staging
spec:
  hard:
    requests.cpu: "4"             # Max total CPU requests across all Pods in namespace
    requests.memory: "8Gi"        # Max total Memory requests across all Pods
    limits.cpu: "8"               # Max total CPU limits
    limits.memory: "16Gi"         # Max total Memory limits
    pods: "10"                    # Max number of Pods allowed in namespace
    services: "5"                 # Max number of Services
    services.loadbalancers: "1"   # Max cloud load balancers
    persistentvolumeclaims: "4"   # Max PVC count
    requests.storage: "100Gi"     # Max total persistent storage allocation

The ResourceQuota Golden Rule

If a ResourceQuota restricts compute resources (requests.cpu or requests.memory), every single Pod submitted to that namespace MUST explicitly specify resource requests (either in its YAML manifest or automatically through an active LimitRange). If requests are omitted and no LimitRange exists, the API server rejects the Pod creation with a 403 Forbidden error (exceeded quota: ... is missing request for cpu).

Quota Scopes and PriorityClasses

ResourceQuotas can be restricted to specific Pod subsets using spec.scopes:

  • Terminating: Applies only to Pods with spec.activeDeadlineSeconds >= 0.
  • NotTerminating: Applies only to long-running Pods (activeDeadlineSeconds unset).
  • BestEffort: Applies only to Pods with BestEffort QoS.
  • NotBestEffort: Applies to Guaranteed and Burstable Pods.
  • scopeSelector: Matches Pods based on PriorityClass names.

5. CKA Exam CLI Commands & Troubleshooting Workflows

# Inspect ResourceQuota status and current utilization in a namespace
kubectl get resourcequota -n staging
kubectl describe resourcequota team-compute-quota -n staging

# Inspect LimitRange rules in a namespace
kubectl describe limitrange core-resource-limits -n staging

# Check live compute utilization of nodes and pods
kubectl top nodes
kubectl top pods -n staging --containers

# Troubleshoot Pod rejection due to quota breach
kubectl get events -n staging --field-selector reason=FailedCreate --sort-by=.metadata.creationTimestamp
Loading diagram...
QoS Classification and Node-Pressure Ranking
Test Your Knowledge

A Pod has two containers: Container A specifies requests: {cpu: 200m, memory: 256Mi} and limits: {cpu: 200m, memory: 256Mi}. Container B specifies requests: {cpu: 100m, memory: 128Mi} and limits: {cpu: 500m, memory: 512Mi}. What is the Quality of Service (QoS) class assigned to this Pod?

A
B
C
D
Test Your Knowledge

An administrator creates a ResourceQuota in namespace 'staging' setting 'hard.requests.cpu: "2"'. A developer tries to deploy a Pod with 'kubectl run nginx --image=nginx'. The command fails with an error stating that the quota was violated. Why was the request rejected even if total namespace CPU usage was 0?

A
B
C
D
Test Your Knowledge

What happens at the operating system level when a container's processes attempt to allocate 1200Mi of RAM on a node when the container manifest sets resources.limits.memory: "1Gi"?

A
B
C
D