LimitRange defines container-level constraints and default resource profiles within a Namespace. While ResourceQuota controls aggregate namespace consumption, LimitRange ensures individual containers are appropriately sized.

Purpose and Scope

LimitRange serves three key functions:

Minimum Resources - Prevent containers from requesting too few resources, which could lead to poor performance or resource starvation.

Maximum Resources - Prevent individual containers from monopolizing cluster resources, even if namespace quota would allow it.

Default Values - Automatically inject requests and limits for containers that don’t specify them, enabling quota enforcement without requiring every Pod to be updated.

LimitRange Constraints

apiVersion: v1
kind: LimitRange
metadata:
  name: resource-constraints
  namespace: development
spec:
  limits:
  - type: Container
    max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "250m"
      memory: "256Mi"

This LimitRange ensures:

  • No container can request more than 2 CPU or 4Gi memory
  • Every container must request at least 100m CPU and 128Mi memory
  • Containers without limits get 500m CPU and 512Mi memory
  • Containers without requests get 250m CPU and 256Mi memory

Default Injection

LimitRange’s default injection is critical when ResourceQuotas are active:

Without LimitRange:

  • ResourceQuota requires all Pods to specify requests/limits
  • Creating Pods without resources specified is rejected
  • Legacy applications must be updated before deployment

With LimitRange:

  • Containers without resources get defaults automatically
  • Quota requirements are satisfied transparently
  • Legacy applications work without modification

This makes LimitRange essential for quota enforcement in environments with diverse workloads.

Relationship to ResourceQuota

LimitRange and ResourceQuota work in concert:

LimitRange (container-level):

min: 128Mi memory
max: 4Gi memory
default: 512Mi memory

ResourceQuota (namespace-level):

requests.memory: "20Gi"

Together:

  • LimitRange ensures each container is between 128Mi and 4Gi
  • ResourceQuota ensures total across all containers ≤ 20Gi
  • Defaults enable quota without requiring explicit resources

This prevents both individual container bloat and namespace over-consumption.

Pod-Level Constraints

LimitRange can also constrain entire Pods:

spec:
  limits:
  - type: Pod
    max:
      cpu: "4"
      memory: "8Gi"

This prevents a single Pod (which might have multiple containers) from consuming excessive resources, even if each container individually is within limits.

Validation and Enforcement

LimitRange validation occurs at admission time:

  1. Pod creation request arrives
  2. LimitRange admission controller checks constraints
  3. Defaults are injected if needed
  4. Min/max constraints are validated
  5. If valid, Pod is created; if not, request is rejected

This means:

  • Existing Pods are unaffected by LimitRange changes
  • Only new Pods are constrained
  • Constraints are enforced before Pods reach the scheduler

Resource Ratio Constraints

LimitRange can enforce ratios between requests and limits:

spec:
  limits:
  - type: Container
    maxLimitRequestRatio:
      cpu: "4"
      memory: "2"

This limits how much “burstable” capacity a container can have:

  • CPU limit can be at most 4x the request
  • Memory limit can be at most 2x the request

This prevents Burstable Pods from being configured with tiny requests but huge limits, which could lead to oversubscription.

Common Patterns

Production namespace - Narrow ranges, high minimums:

min: { cpu: 500m, memory: 1Gi }
max: { cpu: 4, memory: 8Gi }

Development namespace - Wide ranges, low minimums:

min: { cpu: 50m, memory: 64Mi }
max: { cpu: 2, memory: 4Gi }

Batch processing namespace - High maximums, permissive ratios:

max: { cpu: 16, memory: 32Gi }
maxLimitRequestRatio: { cpu: 10 }