Skip to content

How to Set Resource Quotas and Limits in Kubernetes

DodaTech 2 min read

In this tutorial, you'll learn about How to Set Resource Quotas and Limits in Kubernetes. We cover key concepts, practical examples, and best practices.

The Problem

One pod in your Kubernetes namespace consumes all cluster CPU or memory, starving other pods and causing cascading failures. Without ResourceQuotas and LimitRanges, a single misconfigured deployment can take down the entire namespace. Pods with no resource limits can use unlimited host resources, leading to unpredictable scheduling and OOM kills. ResourceQuotas set hard limits on total resource consumption at the namespace level, while LimitRanges enforce per-container minimums and maximums, preventing any single container from monopolizing the cluster.

Quick Fix

1. Create a ResourceQuota for a namespace

apiVersion: v1
kind: ResourceQuota
metadata:
  name: namespace-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "20"
    persistentvolumeclaims: "5"
    configmaps: "10"
    secrets: "10"
    services: "10"

Apply with kubectl apply -f quota.yaml. The quota applies to all pods in the namespace.

2. Create a LimitRange for default limits

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: dev
spec:
  limits:
    - default:
        cpu: "500m"
        memory: 512Mi
      defaultRequest:
        cpu: "200m"
        memory: 256Mi
      max:
        cpu: "2"
        memory: 4Gi
      min:
        cpu: "50m"
        memory: 64Mi
      type: Container

Apply with kubectl apply -f limitrange.yaml. Any pod without explicit limits gets these defaults automatically.

3. Set resource requests and limits on a pod

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: app
      image: nginx
      resources:
        requests:
          cpu: "250m"
          memory: 256Mi
        limits:
          cpu: "500m"
          memory: 512Mi

requests is what the scheduler uses to place the pod. limits is the maximum the container can use.

4. Check current quota usage

kubectl describe quota namespace-quota -n dev

Expected output:

Name:            namespace-quota
Namespace:       dev
Resource         Used  Hard
--------         ----  ----
limits.cpu       750m  8
limits.memory    2Gi   16Gi
pods             5     20
requests.cpu     450m  4
requests.memory  1Gi   8Gi

5. Check limitrange in effect

kubectl describe limitrange default-limits -n dev

6. Handle quota exceeded errors

If you get Error from server (Forbidden): exceeded quota, you have three options:

  • Increase the quota: edit the spec.hard values in the ResourceQuota
  • Reduce resource requests on your pods
  • Delete unused pods to free quota

Use kubectl describe for Detailed Diagnostics

kubectl describe pod <pod-name>
# Events:
#   Type     Reason     Age   From     Message
#   ----     ------     ----  ----     -------
#   Warning  BackOff    5m    kubelet  Back-off restarting failed container

The Events section at the bottom of kubectl describe output is the most valuable diagnostic tool. It shows a chronological log of scheduling failures, image pull errors, and container crashes.

Prevention

  • Create ResourceQuota and LimitRange for every namespace at provisioning time
  • Set requests equal to limits for critical pods to guarantee resources (Guaranteed QoS)
  • Monitor quota usage with kubectl describe quota and set alerts at 80% utilization
  • Use namespace-scoped quotas, not cluster-scoped, for multi-tenant clusters
  • Document the expected resource profile of each deployment so team members set accurate requests and limits from the start

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro