Kubernetes Quality of Service (QoS) Classes¶
π§ What is QoS in Kubernetes?¶
QoS (Quality of Service) defines how Kubernetes prioritizes pods for CPU/memory allocation and eviction under resource pressure.
Every pod falls into one of three QoS classes:
| Class | Priority | Use-case |
|---|---|---|
| Guaranteed | Highest | Critical apps |
| Burstable | Medium | Normal apps |
| BestEffort | Lowest | Test or throwaway |
π§© How Kubernetes Assigns QoS Class¶
QoS is determined per pod, based on the resources (CPU/Memory) defined in each container.
π’ 1. Guaranteed (Highest)¶
Conditions:
- Every container in the pod must define both
requestsandlimits - For each container, the values of
requestsmust equallimits
resources:
requests:
cpu: "1"
memory: "256Mi"
limits:
cpu: "1"
memory: "256Mi"
π¦ Pod QoS Class: Guaranteed
π‘ 2. Burstable (Medium)¶
Conditions:
- At least one container sets a resource
requestorlimit - But not all match exactly, or only
requestsare set
resources:
requests:
cpu: "500m"
π¦ Pod QoS Class: Burstable
π΄ 3. BestEffort (Lowest)¶
Conditions:
- No
requestsorlimitsare defined in any container
resources: {}
π¦ Pod QoS Class: BestEffort
βοΈ Why QoS Class Matters¶
π¨ Under Node Memory Pressure (Eviction):¶
Kubelet evicts pods in this order:
BestEffort > Burstable > Guaranteed
π§ Scheduler decisions (indirectly):¶
While scheduling isn't based on QoS, requests impact scheduling. BestEffort pods don't reserve CPU/memory β easier to schedule but easily evicted.
π₯ Examples and Their QoS Classes¶
| CPU Request | CPU Limit | Memory Request | Memory Limit | Class |
|---|---|---|---|---|
| 1 | 1 | 256Mi | 256Mi | Guaranteed |
| 1 | 2 | 128Mi | 256Mi | Burstable |
| β | β | β | β | BestEffort |
π§ͺ How to Check QoS Class of a Pod¶
kubectl get pod <pod-name> -o jsonpath='{.status.qosClass}'
Example:
kubectl get pod myapp -o jsonpath='{.status.qosClass}'
π LimitRange and QoS Class¶
If you do not define resources: explicitly, but a LimitRange exists, Kubernetes auto-applies default requests/limits β your pod becomes Burstable.
Example:¶
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: dev
spec:
limits:
- default:
cpu: 1
memory: 512Mi
defaultRequest:
cpu: 500m
memory: 256Mi
type: Container
Now even if your Pod YAML has no resources, itβll be assigned
Burstabledue to these defaults.
π§ ResourceQuota + LimitRange + QoS: Interaction¶
- ResourceQuota counts requests and limits toward usage.
- If you don't specify anything, LimitRange might assign defaults, consuming your quota.
- This may cause your pod to be rejected unexpectedly if quota is exceeded.
β οΈ Troubleshooting Unexpected QoS¶
β Why is my pod not Guaranteed?¶
- Check if every container defines both
requestsandlimits - Ensure values are equal
β Why was my pod evicted first?¶
-
Check
kubectl describe podfor: -
Evicted Status: FailedReason: EvictedMessage: The node had condition: [MemoryPressure]
π Summary: When to Use What¶
| Class | Use it when... |
|---|---|
| Guaranteed | Mission-critical apps (DBs, control-plane apps) |
| Burstable | Regular apps needing some level of protection |
| BestEffort | Dev/test, short-lived tools, batch jobs |