ResourceQuota defines aggregated resource consumption limits within a Namespace. While resource profiles specify individual Pod requirements, ResourceQuotas control the total resources all Pods in a namespace can consume collectively.

Purpose and Scope

ResourceQuotas enable multi-tenancy and resource governance by preventing any single namespace from consuming excessive cluster resources. They enforce hard limits on:

Compute Resources:

  • Total CPU requests across all Pods
  • Total memory requests across all Pods
  • Total CPU limits across all Pods
  • Total memory limits across all Pods

Storage Resources:

  • Total PersistentVolumeClaim storage
  • Number of PersistentVolumeClaims
  • Storage requests by storage class

Object Counts:

  • Number of Pods
  • Number of Services
  • Number of ConfigMaps, Secrets
  • Number of other resource types

Resource Aggregation

ResourceQuota aggregates resource profiles from all Pods:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: development
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"

With this quota, the development namespace can run many small Pods or fewer large Pods, as long as:

  • Total CPU requests ≤ 10 cores
  • Total memory requests ≤ 20Gi
  • Total CPU limits ≤ 20 cores
  • Total memory limits ≤ 40Gi
  • Total Pod count ≤ 50

Enforcement

When a ResourceQuota is active in a Namespace:

  1. All Pods must specify resource requests and limits (no BestEffort Pods)
  2. Creating a Pod that would exceed quota is rejected
  3. Existing Pods continue running even if quota is later reduced
  4. Quota is freed when Pods are deleted

This enforcement makes resource planning explicit and prevents accidental resource exhaustion.

Quota Scopes

ResourceQuotas can apply selectively using scopes:

Priority-based:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: high-priority-quota
spec:
  hard:
    cpu: "20"
    memory: "40Gi"
  scopeSelector:
    matchExpressions:
    - operator: In
      scopeName: PriorityClass
      values: ["high-priority"]

This limits resources for Pods with specific priority classes, enabling different quotas for different priority levels.

QoS-based:

scopeSelector:
  matchExpressions:
  - operator: In
    scopeName: BestEffort

Scope to specific QoS classes, though BestEffort Pods typically aren’t allowed when quotas are active.

Relationship to LimitRange

ResourceQuota and LimitRange work together:

ResourceQuota:

  • Namespace-level aggregate limits
  • “This namespace can use at most 20Gi memory total”
  • Prevents any team from over-consuming

LimitRange:

  • Container-level min/max/default limits
  • “Each container must request between 128Mi and 2Gi”
  • Ensures individual Pods are right-sized

Together they provide both aggregate governance and individual container sanity checks.

Multi-Tenancy Pattern

A common pattern for multi-tenant clusters:

# Production namespace - generous quota
apiVersion: v1
kind: ResourceQuota
metadata:
  name: prod-quota
  namespace: production
spec:
  hard:
    requests.cpu: "100"
    requests.memory: "200Gi"
---
# Development namespace - restricted quota
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: development
spec:
  hard:
    requests.cpu: "20"
    requests.memory: "40Gi"

Combined with Namespace RBAC, this ensures development workloads can’t starve production resources.

Capacity Planning

ResourceQuotas enable capacity planning by:

  1. Summing quotas across all namespaces
  2. Comparing to total cluster capacity
  3. Identifying over-subscription or under-utilization
  4. Adjusting quotas based on actual usage patterns

Combined with resource profiles and Vertical Pod Autoscaler recommendations, quotas help align resource allocation with actual needs.