Home DevOps Kubernetes LimitRanges and ResourceQuotas: Stop Your Cluster from Starving
Intermediate 3 min · July 18, 2026
Kubernetes LimitRanges and ResourceQuotas: Resource Governance

Kubernetes LimitRanges and ResourceQuotas: Stop Your Cluster from Starving

Kubernetes resource governance with LimitRanges and ResourceQuotas.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.

Follow
Production
production tested
July 18, 2026
last updated
2,466
articles · all by Naren
Before you start⏱ 30 min
  • Basic Kubernetes knowledge: pods, namespaces, kubectl
  • Familiarity with YAML manifests
  • Understanding of CPU/memory resource concepts
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

Use ResourceQuotas to set hard caps on total CPU and memory per namespace, and LimitRanges to enforce per-pod resource requests and limits. Without them, a single misconfigured deployment can exhaust cluster resources and starve other workloads.

✦ Definition~90s read
What is Kubernetes LimitRanges and ResourceQuotas?

LimitRanges set min/max/default resource limits per pod or container within a namespace. ResourceQuotas cap total resource usage across all pods in a namespace. Together they enforce resource governance, preventing any single team or app from consuming cluster capacity without restraint.

Think of a shared office kitchen.
Plain-English First

Think of a shared office kitchen. ResourceQuota is the rule that says 'no one can take more than 10 cups of coffee a day total.' LimitRange is the rule that says 'each person can only fill their mug up to 12 ounces.' Without both, one person could brew a whole pot for themselves and leave everyone else with nothing.

You've deployed your microservices, everything's humming, and then one day a team deploys a cron job that requests 32GB of memory. Your cluster runs out, pods get evicted, and your payments service goes down at 3am. That's not bad luck — that's missing resource governance.

Kubernetes gives you two tools to prevent this: LimitRanges and ResourceQuotas. They're not optional in any multi-tenant or production cluster. Without them, you're one resources: {} away from a cluster-wide outage.

By the end of this article, you'll know exactly how to configure LimitRanges and ResourceQuotas to protect your cluster, enforce team fairness, and debug the inevitable 'exceeded quota' errors without panicking.

Why You Need Resource Governance: The Noisy Neighbor Problem

Without resource governance, any pod can request any amount of CPU or memory. In a multi-team cluster, one team's misconfigured deployment can consume all available resources, starving other teams' pods. This is the noisy neighbor problem.

ResourceQuotas solve this by capping total resource usage per namespace. LimitRanges solve it by enforcing per-pod resource boundaries. Together they ensure fair sharing and prevent a single bad deployment from taking down the cluster.

Before these tools existed, teams had to rely on manual monitoring and hope. I've seen a single node-exporter daemonset with resources: {} consume 8GB on every node because it defaulted to unlimited. That's a production incident waiting to happen.

noisy-neighbor-example.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// io.thecodeforge — DevOps tutorial

# Without resource limits, this pod can use all node resources
apiVersion: v1
kind: Pod
metadata:
  name: greedy-pod
spec:
  containers:
  - name: stress
    image: polinux/stress
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "64G", "--vm-hang", "1"]
    # No resources specified — will consume 64GB if available
Output
Pod runs and consumes 64GB, starving other pods on the node. No error until OOM.
⚠ Production Trap:
Never deploy a pod without resource requests and limits in a shared cluster. Even sidecar containers like Istio proxies can consume significant resources if unconstrained.

ResourceQuotas: The Hard Cap Per Namespace

A ResourceQuota sets a hard limit on total resource usage within a namespace. You can cap CPU, memory, storage, and even object counts (pods, services, etc.). Once the quota is reached, no new pods can be created until resources are freed.

This is your first line of defense against a team accidentally consuming the entire cluster. But there's a catch: you must set resource requests on every pod, or the quota won't be enforced. Kubernetes rejects pods without requests if a quota exists.

I've seen teams create a quota and then wonder why their pods won't start — they forgot to add resources.requests to their deployments. The error message exceeded quota is clear, but people still miss it.

resource-quota-example.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// io.thecodeforge — DevOps tutorial

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-quota
  namespace: analytics
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "10"
    persistentvolumeclaims: "5"
    requests.storage: "50Gi"
Output
Applied. Any pod in 'analytics' namespace must have resource requests. Total CPU request cannot exceed 4 cores, total memory request cannot exceed 8Gi.
🔥Senior Shortcut:
Always set both requests and limits in your quota. Setting only requests means pods can have unlimited limits, which can still cause resource exhaustion.

LimitRanges: Per-Pod Resource Boundaries

A LimitRange enforces min, max, and default resource values per pod or container within a namespace. This prevents a single pod from requesting an absurd amount of resources while also ensuring every pod gets a baseline.

Without LimitRanges, a team could create a pod with requests.memory: 100Gi — which would be denied by quota if the total exceeds it, but if quota has room, it's allowed. LimitRange catches this at the pod level.

LimitRanges also set default requests and limits for pods that don't specify them. This is useful but dangerous: if your app needs 2Gi but the default is 512Mi, it will get OOMKilled. Always verify defaults match your workload.

limit-range-example.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// io.thecodeforge — DevOps tutorial

apiVersion: v1
kind: LimitRange
metadata:
  name: container-limits
  namespace: analytics
spec:
  limits:
  - max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "200m"
      memory: "512Mi"
    type: Container
Output
Applied. Any container in 'analytics' must have CPU between 100m and 2, memory between 128Mi and 4Gi. If no resources specified, defaults are applied.
⚠ Never Do This:
Don't set defaultRequest higher than default for the same resource. Kubernetes will reject the LimitRange with an error like Invalid value: "...": must be less than or equal to ... limit.

How LimitRanges and ResourceQuotas Interact

LimitRanges and ResourceQuotas work together but enforce different scopes. LimitRanges validate each pod individually at creation time. ResourceQuotas track cumulative usage across all pods in the namespace.

When a pod is created, Kubernetes first checks the LimitRange (if any) to ensure the pod's resources are within min/max. Then it checks the ResourceQuota to ensure the new pod doesn't exceed the namespace's total cap.

A common pitfall: if you set a LimitRange with a max that is larger than the remaining quota, a pod that passes the LimitRange check may still fail the quota check. This is correct behavior, but it can confuse developers who only see the quota error.

interaction-example.yamlYAML
1
2
3
4
5
6
// io.thecodeforge — DevOps tutorial

# Assume quota: requests.memory: 8Gi, used: 7.5Gi
# LimitRange: max memory: 4Gi
# A pod requesting 1Gi memory passes LimitRange (1Gi < 4Gi) but fails quota (7.5+1=8.5 > 8Gi)
# Error: 'exceeded quota: team-quota, requested: memory=1Gi, used: memory=7.5Gi, limited: memory=8Gi'
Output
Pod creation fails with quota exceeded error, even though it passed LimitRange validation.
🔥Interview Gold:
The order of validation is: LimitRange first, then ResourceQuota. If both fail, you only see the first error (LimitRange). This can mask quota issues during debugging.

Production Patterns: Setting Realistic Defaults

In production, you need to balance protection with flexibility. Setting overly restrictive defaults breaks deployments. Setting none leaves you exposed.

Pattern 1: Start with generous limits and tighten over time. Set max high enough to accommodate any reasonable workload, then monitor actual usage and reduce.

Pattern 2: Use defaultRequest and default to match your most common workload. If most services use 256Mi-512Mi, set defaults accordingly. For outliers, teams must explicitly override.

Pattern 3: Always set min to prevent zero-request pods. A pod with requests.cpu: 0 can still consume CPU, causing unpredictability. Set min to at least 10m or 50m.

production-patterns.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// io.thecodeforge — DevOps tutorial

apiVersion: v1
kind: LimitRange
metadata:
  name: production-limits
  namespace: production
spec:
  limits:
  - max:
      cpu: "8"
      memory: "32Gi"
    min:
      cpu: "10m"
      memory: "64Mi"
    default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "250m"
      memory: "512Mi"
    type: Container
Output
Applied. Pods must request at least 10m CPU and 64Mi memory. Defaults are 250m/512Mi. Maximum is 8 CPU / 32Gi memory.
💡Senior Shortcut:
Use kubectl describe quota and kubectl describe limitrange to see current usage and enforcement. This is your first step when debugging resource issues.

When Not to Use LimitRanges and ResourceQuotas

In a single-team cluster where everyone trusts each other, you might skip these. But even then, a misconfigured deployment can cause issues. I'd still recommend at least a ResourceQuota.

For ephemeral clusters (CI/CD, test environments), strict quotas can cause unnecessary failures. Consider setting high quotas or none at all for short-lived clusters.

If you use autoscaling (Cluster Autoscaler), quotas can prevent the cluster from scaling up because new pods are rejected before the autoscaler can add nodes. This is a known pain point — you need to ensure quota is high enough to allow burst scaling.

🔥Production Trap:
If your Cluster Autoscaler is not adding nodes, check if ResourceQuota is blocking pod creation. The autoscaler only triggers when pods are pending due to insufficient node resources, not quota.

Debugging Resource Governance Issues

When a pod fails to start, the error message usually points to quota or limit range. But sometimes it's not obvious.

Step 1: Run kubectl describe pod <pod-name> and look for events at the bottom. You'll see FailedCreate or Failed with a reason.

Step 2: Check quota: kubectl get quota -n <ns> -o yaml. Look at status.hard vs status.used.

Step 3: Check LimitRange: kubectl describe limitrange -n <ns>. Verify min/max/defaults.

Step 4: If the pod has no resources set, the LimitRange defaults are applied. Check if those defaults are appropriate.

I once spent an hour debugging a pod that kept getting OOMKilled. Turns out the LimitRange default memory limit was 256Mi, but the app needed 1Gi. The fix was to set explicit resources on the deployment.

debug-commands.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
// io.thecodeforge — DevOps tutorial

# Check pod events
kubectl describe pod my-pod -n my-namespace

# Check quota usage
kubectl get quota -n my-namespace -o yaml

# Check LimitRange details
kubectl describe limitrange -n my-namespace

# See all resources in namespace
kubectl get pods -n my-namespace -o custom-columns=NAME:.metadata.name,REQ_CPU:.spec.containers[*].resources.requests.cpu,REQ_MEM:.spec.containers[*].resources.requests.memory,LIM_CPU:.spec.containers[*].resources.limits.cpu,LIM_MEM:.spec.containers[*].resources.limits.memory
Output
Output shows pod resource requests and limits. Useful for spotting pods without resources.
💡Senior Shortcut:
Create a custom column output for resources as shown above. It's the fastest way to audit all pods in a namespace.

Common Mistakes and How to Avoid Them

Mistake 1: Setting defaultRequest higher than default for the same resource. Kubernetes rejects the LimitRange. Fix: ensure defaultRequest <= default.

Mistake 2: Forgetting to set resource requests on pods when a quota exists. Pods fail with exceeded quota. Fix: always set resources.requests in your deployments.

Mistake 3: Setting quota too low, causing valid deployments to fail. Fix: monitor usage over time and adjust quota accordingly. Use kubectl describe quota to see usage.

Mistake 4: Not setting limits.storage in quota, allowing unbounded PVC usage. Fix: always include requests.storage and persistentvolumeclaims in quota.

⚠ The Classic Bug:
Setting requests.cpu: 0 in a LimitRange min is allowed but defeats the purpose. A pod with zero CPU request can still use CPU, causing unpredictable scheduling. Always set a positive min.
● Production incidentPOST-MORTEMseverity: high

The 4GB Container That Kept Dying

Symptom
A data-processing pod in the analytics namespace kept restarting with OOMKilled every 10 minutes.
Assumption
The team assumed the pod had a memory leak and spent days profiling the application.
Root cause
The namespace had a LimitRange with defaultRequest: 512Mi and default: 1Gi for memory, but the pod's deployment didn't set any resources. The LimitRange applied defaults: request 512Mi, limit 1Gi. The pod's actual memory usage was 2Gi, so it got OOMKilled immediately.
Fix
Set explicit resources in the deployment: resources.requests.memory: 2Gi and resources.limits.memory: 4Gi. Also updated the LimitRange to have maxLimitRequestRatio: 2 to catch future mismatches.
Key lesson
  • Always set explicit resource requests and limits on your pods.
  • Relying on LimitRange defaults is a trap — they silently apply values that may not match your workload.
Production debug guideSystematic recovery paths for the failure modes engineers actually hit.3 entries
Symptom · 01
Pod stuck in Pending with event FailedCreate: quota exceeded
Fix
1. Run kubectl describe quota -n <ns> to see current usage vs hard limits. 2. Identify which resource is exhausted (CPU, memory, pods). 3. Either increase quota or reduce resource requests of pending pods.
Symptom · 02
Pod starts but immediately gets OOMKilled
Fix
1. Run kubectl describe pod <pod> and check container resource limits. 2. Run kubectl describe limitrange -n <ns> to see default limits. 3. If default limit is too low, set explicit resources on the deployment.
Symptom · 03
Pod fails with Invalid: spec.containers[0].resources.requests: Invalid value: ...: must be less than or equal to ... limit
Fix
1. Check LimitRange min/max values with kubectl describe limitrange -n <ns>. 2. Adjust pod resource requests/limits to fall within the range.
★ Kubernetes LimitRanges and ResourceQuotas: Resource Governance Triage Cheat SheetFirst-response commands for when things go wrong — copy-paste ready.
Pod pending with `0/1 nodes are available: Insufficient cpu`
Immediate action
Check if quota is exhausted
Commands
kubectl describe quota -n <ns>
kubectl top pods -n <ns>
Fix now
Reduce resource requests or increase quota hard limits
Pod fails with `exceeded quota: <name>`+
Immediate action
Check quota usage
Commands
kubectl get quota -n <ns> -o yaml
kubectl describe quota -n <ns>
Fix now
Delete unused pods or increase quota
Pod OOMKilled repeatedly+
Immediate action
Check LimitRange defaults
Commands
kubectl describe limitrange -n <ns>
kubectl get pod <pod> -o yaml | grep -A5 resources
Fix now
Set explicit memory limit in deployment spec
Pod fails with `Invalid: spec.containers[0].resources.requests: Invalid value`+
Immediate action
Check LimitRange min/max
Commands
kubectl describe limitrange -n <ns>
kubectl get limitrange -n <ns> -o yaml
Fix now
Adjust pod resources to fit within LimitRange
Feature / AspectResourceQuotaLimitRange
ScopeNamespace-level total resource capPer-pod or per-container resource boundaries
EnforcesCumulative usage across all podsIndividual pod resource min/max/defaults
RequiresPods must have resource requestsPods must have resources within min/max
Default valuesNoYes — sets default request and limit
Object count limitsYes (pods, services, etc.)No
Storage limitsYesNo
⚙ Quick Reference
5 commands from this guide
FileCommand / CodePurpose
noisy-neighbor-example.yamlapiVersion: v1Why You Need Resource Governance
resource-quota-example.yamlapiVersion: v1ResourceQuotas
limit-range-example.yamlapiVersion: v1LimitRanges
production-patterns.yamlapiVersion: v1Production Patterns
debug-commands.shkubectl describe pod my-pod -n my-namespaceDebugging Resource Governance Issues

Key takeaways

1
Always set both ResourceQuotas and LimitRanges in any multi-tenant or production namespace
they prevent the noisy neighbor problem.
2
LimitRanges are checked before ResourceQuotas; a pod can pass LimitRange but fail quota if cumulative usage is too high.
3
Never rely on LimitRange defaults for production workloads
always set explicit resource requests and limits on your pods.
4
The order of validation is LimitRange first, then ResourceQuota. If both fail, you only see the first error.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
What happens when a pod's resource request exceeds the remaining Resourc...
Q02SENIOR
When would you choose to set a ResourceQuota without a LimitRange in a p...
Q03SENIOR
A pod is stuck in Pending with event 'FailedCreate: quota exceeded' but ...
Q04JUNIOR
What is the purpose of `maxLimitRequestRatio` in a LimitRange?
Q05SENIOR
You have a ResourceQuota that sets `requests.memory: 8Gi` and a LimitRan...
Q06SENIOR
How would you design resource governance for a cluster with 10 teams, ea...
Q01 of 06SENIOR

What happens when a pod's resource request exceeds the remaining ResourceQuota but is within the LimitRange? Does the pod get created?

ANSWER
No, the pod is rejected. Kubernetes checks LimitRange first, then ResourceQuota. Even if the pod passes LimitRange, it fails if the quota would be exceeded. The error message will say 'exceeded quota'.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
What is the difference between a Kubernetes LimitRange and a ResourceQuota?
02
Can I set a ResourceQuota without a LimitRange?
03
How do I debug a pod that fails with 'exceeded quota'?
04
What happens if a pod doesn't specify resource requests but a ResourceQuota exists?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Lessons pulled from things that broke in production.

Follow
Verified
production tested
July 18, 2026
last updated
2,466
articles · all by Naren
🔥

That's Kubernetes. Mark it forged?

3 min read · try the examples if you haven't

Previous
Kustomize: Declarative Configuration Management
37 / 43 · Kubernetes
Next
Kubernetes Volumes and Storage — PV, PVC, StorageClass