What Are the Pod Quality of Service (QoS) Classes?
Kubernetes assigns one of three QoS classes to every Pod -- Guaranteed, Burstable, or BestEffort -- based on the resource requests and limits of its containers. The QoS class determines eviction priority when a node runs low on resources: BestEffort Pods are evicted first, then Burstable, then Guaranteed.
Detailed Answer
Kubernetes automatically assigns a Quality of Service (QoS) class to every Pod based on the CPU and memory resource requests and limits defined on its containers. The QoS class is a key factor in determining which Pods are evicted first when a node is under resource pressure.
The Three QoS Classes
Guaranteed
A Pod receives the Guaranteed QoS class when every container has CPU and memory requests and limits set, and the requests equal the limits.
apiVersion: v1
kind: Pod
metadata:
name: guaranteed-pod
spec:
containers:
- name: app
image: myapp/server:2.1
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "256Mi"
Guaranteed Pods:
- Get the highest eviction protection -- they are the last to be evicted.
- Are placed in the most protected cgroup tier.
- Have predictable performance because they cannot burst beyond their requests.
Burstable
A Pod receives the Burstable QoS class when at least one container has a resource request or limit set, but the Pod does not meet the Guaranteed criteria.
apiVersion: v1
kind: Pod
metadata:
name: burstable-pod
spec:
containers:
- name: app
image: myapp/server:2.1
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "1"
memory: "512Mi"
Burstable Pods:
- Can use more resources than requested, up to their limits.
- Are evicted after BestEffort Pods but before Guaranteed Pods.
- Among Burstable Pods, eviction order is based on how much memory the Pod is using relative to its request.
BestEffort
A Pod receives the BestEffort QoS class when no container specifies any CPU or memory requests or limits.
apiVersion: v1
kind: Pod
metadata:
name: besteffort-pod
spec:
containers:
- name: app
image: myapp/server:2.1
# No resources block at all
BestEffort Pods:
- Have the lowest priority -- they are evicted first during resource pressure.
- Can consume any available resources on the node (no guarantees).
- Are suitable only for non-critical batch jobs or development workloads.
How to Check a Pod's QoS Class
kubectl get pod <pod-name> -o jsonpath='{.status.qosClass}'
# Or see it in the describe output
kubectl describe pod <pod-name> | grep "QoS Class"
Eviction Order Under Memory Pressure
When the kubelet detects that node memory is running low (based on eviction thresholds), it evicts Pods in this order:
- BestEffort Pods -- evicted first, sorted by memory usage.
- Burstable Pods -- evicted next, sorted by memory usage relative to their requests. A Pod using 400Mi against a 256Mi request is evicted before one using 300Mi against a 256Mi request.
- Guaranteed Pods -- evicted last, only when no other Pods can be evicted and the system is critically low on memory.
Node memory pressure detected
|
v
Evict BestEffort Pods (highest memory usage first)
|
v
Still under pressure? Evict Burstable Pods (highest usage/request ratio first)
|
v
Still under pressure? Evict Guaranteed Pods (last resort)
QoS and the OOM Killer
If the kubelet's eviction mechanism is too slow and the node's kernel runs out of memory, the Linux OOM killer activates. It assigns an oom_score_adj value based on the QoS class:
| QoS Class | oom_score_adj | OOM Kill Priority | |-----------|--------------|-------------------| | Guaranteed | -997 | Lowest (almost never killed) | | Burstable | 2-999 (varies by usage) | Medium | | BestEffort | 1000 | Highest (killed first) |
Common QoS Scenarios
| Container A | Container B | Pod QoS Class | |-------------|-------------|---------------| | requests=limits=500m CPU, 256Mi | requests=limits=250m CPU, 128Mi | Guaranteed | | requests=250m CPU, 128Mi; limits=500m CPU, 256Mi | (single container) | Burstable | | requests=500m CPU, 256Mi; limits=500m CPU, 256Mi | no resources set | Burstable | | no resources | no resources | BestEffort |
Notice that if any single container in a multi-container Pod lacks resource specifications, the entire Pod cannot be Guaranteed.
Choosing the Right QoS Class
Use Guaranteed for:
- Production databases and stateful workloads
- Latency-sensitive services
- Core infrastructure components (DNS, monitoring)
Use Burstable for:
- Most web application workloads
- Services that have variable load but need baseline guarantees
- Batch jobs that benefit from burst capacity
Use BestEffort for:
- Development and testing Pods
- Non-critical batch processing
- Preemptible workloads that can be restarted without consequence
Best Practices
- Always set resource requests and limits in production -- never deploy BestEffort Pods to production clusters.
- Use Guaranteed for critical workloads to maximize eviction protection.
- Set requests equal to limits for predictable performance -- this also gives you Guaranteed QoS.
- Monitor node resource utilization -- QoS classes only matter when nodes are under pressure.
- Combine QoS with Pod Priority to get fine-grained control over which workloads survive resource contention.
Why Interviewers Ask This
This question tests your understanding of Kubernetes resource management and node-level eviction behavior. Interviewers want to know if you can design workloads that survive resource pressure gracefully.
Common Follow-Up Questions
Key Takeaways
- Guaranteed: requests == limits for all containers. Highest eviction protection.
- Burstable: at least one container has requests or limits set, but not all match. Medium protection.
- BestEffort: no requests or limits on any container. Evicted first.