Skip to main content
RunBook Academy

KubernetesCVIII · ResourceQuotaResourceQuota

Compute quotas — CPU and memory budgets per namespace

Advanced⏱ ~16 minkubectl

What you'll learn

  • Configure compute quotas (requests.cpu, requests.memory, limits.cpu, limits.memory)
  • Reason about requests vs limits and the overcommit strategy
  • Monitor quota utilisation
  • Apply the operational discipline of setting compute quotas deliberately

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Compute quotas bound the CPU and memory that a namespace can request or limit. This lesson walks the compute quota fields, the overcommit strategy, the observability, and the operational discipline.

The compute quota fields

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: tenant-a-prod
spec:
  hard:
    requests.cpu: "32"
    requests.memory: 64Gi
    limits.cpu: "64"
    limits.memory: 128Gi

The four fields:

  • requests.cpu. Sum of all Pods’ CPU requests cannot exceed 32 cores.
  • requests.memory. Sum of all Pods’ memory requests cannot exceed 64 GiB.
  • limits.cpu. Sum of all Pods’ CPU limits cannot exceed 64 cores.
  • limits.memory. Sum of all Pods’ memory limits cannot exceed 128 GiB.

The scheduler uses requests to decide if a Pod fits on a node. The kubelet uses limits to enforce runtime limits. The quota bounds both, and it does so at admission — before the scheduler ever sees the Pod.

The overcommit strategy

flowchart LR
    A[Requests] --> B[Drives scheduling]
    A --> C[Used for bin-packing]
    D[Limits] --> E[Runtime ceiling]
    D --> F["CPU throttling, memory OOM"]
    G["Overcommit: requests < limits"]
    G --> H[70% of limits as requests]
    H --> I[30% headroom for bursting]

The overcommit strategy:

  • requests at 70% of limits. A Pod requests 70% of its limit; the scheduler reserves 70% but the Pod can burst to 100%.
  • 30% headroom. The scheduler has headroom for bursting workloads (rollouts, scaling events).
  • Quality of Service. Pods with requests == limits are Guaranteed; Pods with requests < limits are Burstable.

The trade-off: more headroom allows more bursting but reduces scheduling efficiency; less headroom maximises density but risks OOM kills.

LimitRange for defaults

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: tenant-a-prod
spec:
  limits:
    - type: Container
      default:
        cpu: 500m
        memory: 512Mi
      defaultRequest:
        cpu: 100m
        memory: 128Mi
      max:
        cpu: 2
        memory: 4Gi

LimitRange supplies the values for Pods that do not set their own. Without it, a Pod submitted into a namespace that has a compute quota and that declares neither requests nor limits for the constrained resource is rejected at admission. The quota is not bypassed — the Pod simply never gets created, and the workload author sees a forbidden: failed quota error instead of a running Pod.

Observability

kubectl describe resourcequota compute-quota -n tenant-a-prod
Name:            compute-quota
Namespace:       tenant-a-prod
Resource         Used    Hard
--------         ----    ----
requests.cpu     24      32
requests.memory  48Gi    64Gi
limits.cpu       48      64
limits.memory    96Gi    128Gi

The Used column shows current usage; the Hard column shows the quota. Monitor the Used vs Hard ratio to detect approaching-quota namespaces.

kube_resourcequota{resource="requests.cpu", type="used"} / kube_resourcequota{resource="requests.cpu", type="hard"}

The type label is what separates the two series; without it the numerator matches both used and hard and the expression returns nothing useful.

Alert when utilisation exceeds 80%:

- alert: ResourceQuotaNearLimit
  expr: kube_resourcequota{resource="requests.cpu", type="used"} / kube_resourcequota{resource="requests.cpu", type="hard"} > 0.8
  for: 5m
  annotations:
    summary: "Namespace {{ $labels.namespace }} is approaching CPU quota"

Setting compute quotas

flowchart LR
    A[Setting compute quotas] --> B[Start with observed usage]
    B --> C[Add 30-50% headroom]
    C --> D[Set as requests quota]
    D --> E[Set limits at 2x requests]
    E --> F[Monitor and adjust]

The discipline:

  1. Start with observed usage. Use metrics to determine current CPU and memory consumption.
  2. Add 30-50% headroom. Allow room for growth and bursts.
  3. Set as requests quota. requests.cpu and requests.memory.
  4. Set limits at 2x requests. limits.cpu and limits.memory allow bursting.
  5. Monitor and adjust. Quarterly review.

Quiz

Knowledge check · 4 questions

  1. Q1. Why can a namespace hit its `requests.cpu` quota while its Pods use little CPU?

  2. Q2. Raising a ResourceQuota is the correct first response to a namespace that has exhausted it.

  3. Q3. An HPA cannot scale out although the namespace's CPU request budget has headroom; find the exhausted quota key and clear it.

    `checkout` has an HPA with `maxReplicas: 40` and has been pinned at 32 replicas for an hour while CPU utilisation sits at 92 per cent. `kubectl describe resourcequota compute -n checkout-prod` shows `requests.cpu 25600m / 64` and `limits.cpu 64 / 64`. The ReplicaSet's events read `exceeded quota: compute, requested: limits.cpu=2, used: limits.cpu=64, limited: limits.cpu=64`. Each container declares `requests.cpu: 800m` and `limits.cpu: 2`.

  4. Q4. A namespace's `requests.cpu` quota is 32 and the cluster has 200 idle cores. A Pod requesting 40 cores is rejected. Which component rejected it, and does raising the quota make the Pod schedulable?

Passing score: 75%. Answers are checked in this browser.

The operational discipline

Compute quotas in production rest on five non-negotiable elements:

  • LimitRange for defaults. Every Pod gets requests, so nothing is rejected for omitting them.
  • requests at 70% of limits. Bursting headroom.
  • Monitor utilisation. Alert when approaching quota.
  • Set quotas deliberately. Not too tight, not too loose.
  • Review quarterly. Workloads change; quotas must adapt.

Compute quotas are production contracts. Treat them deliberately and monitor the contract.