Skip to main content
ResourceQuota and LimitRange define namespace-level budgets and defaults for container resource requests and limits in Kubernetes. Choosing good values is a practical engineering problem — there are no universal answers, but there are repeatable methods you can use to set sensible defaults and iterate from real usage data. In this lesson you’ll get:
  • An overview of the common challenges when selecting ResourceQuota and LimitRange values.
  • Practical guidance for choosing defaults for typical workloads.
  • A method to design environment-specific quotas (namespace tiers).
  • A process to refine values using actual usage data.
Begin with a common anti-pattern many platform teams encounter. A platform team at a logistics company rolled out a flat ResourceQuota of 2 CPU per namespace. Within 24 hours the data pipeline team’s batch job failed to deploy because it needed 8 CPUs per container, while a lightweight API team used only 200m CPU — wasting most of their allocation. A one-size-fits-all quota helped no one.
A slide titled "The Problem" showing a 2 CPU per-namespace resource quota split between a "Data Pipeline Team" and a "Lightweight API Team." The Data Pipeline side shows a red 2 CPU allocation and a monitor labeled "Deployment: Failed Needs 8 CPU," while the API side shows an unused 2 CPU allocation.
The four practical questions platform teams usually ask — none have a single correct answer:
  1. What should the default CPU request be?
    • It depends on workload mix. Web APIs frequently use ~100–500m CPU, data pipelines ~2 CPU, ML training 8+ CPUs. No single default fits all workloads.
  2. How much memory quota per namespace is fair?
    • Depends on number of services, memory intensity, and whether the namespace is dev, staging, or production.
  3. How many Pods per namespace is reasonable?
    • Depends on deployment patterns. A single microservice with a few replicas needs few pods; many microservices with autoscaling may require hundreds.
  4. What if defaults are too restrictive?
    • Defaults that are too low cause frequent increase requests; too high and governance is ineffective. Use a methodology and iterate with data.
Two high-level design principles:
  • Use LimitRange to inject reasonable defaults for the most common workloads while allowing teams to override when necessary.
  • Implement namespace tiers (small, medium, large) with ResourceQuota templates tailored to each purpose.
Consider three common workload profiles: web API, data pipeline, and ML training. They have distinct resource footprints — most organizations run a mix of lightweight services, medium-weight batch jobs, and heavy compute workloads.
A slide titled "One Size Doesn't Fit All" showing three workload types—Web API (100m CPU, 128Mi RAM), Data Pipeline (2 CPU, 4Gi RAM), and ML Training (8 CPU, 32Gi RAM)—to illustrate different resource profiles. A short banner at the bottom notes most organizations run a mix of light services, medium batch jobs, and heavy compute workloads.
Dev, staging, and production namespaces should be sized differently:
  • Dev: lower quotas for experimentation.
  • Staging: capacity to run production-like tests.
  • Production: higher quotas and stricter controls for customer-facing workloads.
Sensible starting points and multiplier guidance The diagram below shows recommended starting points — LimitRange defaults (left) for lightweight services and ResourceQuota starting points (right) for a typical team running ~5–15 microservices. These are starting points to be validated and adjusted with telemetry. For burst multipliers:
  • CPU: 3×–5× request → limit (CPU throttling is graceful).
  • Memory: 2×–3× request → limit (avoid OOMs; be conservative).
A lower multiplier (2×) gives tighter control; a higher multiplier (5×) permits more burst but increases overcommit risk.
A slide titled "Sensible Starting Points" showing two panels: "LimitRange Defaults" with default CPU/memory request and limit values (defaultRequest.cpu 100m, default.cpu 500m, defaultRequest.memory 128Mi, default.memory 512Mi) and a note that limits are ~2–5x requests. The right panel, "ResourceQuota per Namespace," lists suggested quotas (requests.cpu 4–8 cores, limits.cpu 16–32 cores, requests.memory 8–16Gi, count/pods 10–50) to adjust by team size.
Quick reference table for multipliers and priorities LimitRange — what the fields mean LimitRange injects defaults only for containers that omit requests/limits and enforces min/max bounds. Key fields:
  • spec.limits[].default: Values injected into containers that omit requests/limits.
  • spec.limits[].defaultRequest: Default request values injected similarly.
  • spec.limits[].min and spec.limits[].max: Optional hard bounds — the API server rejects Pod/container specs outside these ranges.
  • spec.limits[].type: Container applies per container; Pod applies per pod (use Pod for pod-level control).
Important: If a developer sets explicit requests/limits, LimitRange will not override them — it only injects defaults and enforces bounds.
ResourceQuota — what to quota and why ResourceQuota caps the total resource usage in a namespace and complements LimitRange:
  • requests.* fields cap the sum of container requests (scheduling budget).
  • limits.* fields cap the sum of container limits (runtime burst budget).
  • pods caps the number of Pods — prevents accidental sprawl.
  • You can also quota object counts (e.g., services, configmaps) and storage.
Always pair a ResourceQuota with a LimitRange so pods have injected requests/limits and quota counting behaves predictably.
Namespace tiers: right-size by purpose Create tiered quota templates and assign namespaces to tiers rather than using a single quota per namespace. Create reusable quota templates for each tier, apply consistently, and review assignments regularly (quarterly is a reasonable cadence).
A slide titled "Namespace Tiers: Right-Size by Purpose" showing three cards — Small (Dev), Medium (Staging), and Large (Production) — each listing CPU requests, memory requests, pod count, storage, and a short intended use case.
Operationalizing and iterating
  1. Monitor
  2. Adjust
    • After 2–4 weeks of telemetry, adjust LimitRange defaults and ResourceQuota values.
    • Use peak usage (not just averages) to size production quotas. For dev, favor tighter limits that still permit experimentation.
  3. Educate
    • Provide guidance describing when teams should request higher quotas vs. when to optimize their workloads.
  4. Automate
    • Template quota tiers and provide a self-service request/review workflow for quota changes that requires justification.
These are starting points, not final answers. Deploy defaults, monitor for 2–4 weeks, and iterate. The worst mistake is setting quotas once and never revisiting them.
Pair ResourceQuota and LimitRange: ResourceQuota enforces the namespace budget; LimitRange injects defaults so pods count correctly toward quotas and are not rejected for missing requests/limits.
Five key takeaways
  1. Start with reasonable defaults, then iterate based on telemetry.
  2. Use namespace tiers (small, medium, large) to match environment purpose and team needs.
  3. Always pair ResourceQuota with LimitRange so pods have resource values and quota accounting works predictably.
  4. Monitor real usage and adjust — governance is not set-and-forget.
  5. Good governance enables teams by making resource usage predictable, fair, and reliable.
Further reading and references

Watch Video

Practice Lab