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:
- Pod creation request arrives
- LimitRange admission controller checks constraints
- Defaults are injected if needed
- Min/max constraints are validated
- 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 }