Taming namespace disk: why ephemeral-storage quotas in Kubernetes surprise teams and how to make them behave

Namespaces and ResourceQuotas are the control knobs operators use to divide cluster resources among teams. CPU and memory quotas tend to behave the way you expect: you set a limit, workloads that request more get rejected, and the math is straightforward. Ephemeral storage (the disk used by containers for logs, scratch space, and emptyDir volumes), however, is the sneaky sibling — it often doesn’t obey quotas unless several conditions are met. This article explains the common gotchas, why they happen, and a practical checklist (plus example YAML) to get ephemeral-storage quotas working reliably at the namespace level.

Why ephemeral-storage is different (an analogy)

The enforcement model you must understand

Common gotchas and surprises

  1. Pods without ephemeral-storage requests aren’t always counted
    • If pods omit ephemeral-storage requests or limits, the ResourceQuota mechanism may not count their ephemeral usage toward namespace totals. This means a poorly specified workload can silently blow past the quota. (v1-33.docs.kubernetes.io)
  2. Container logs and writable layers count, sometimes unexpectedly
    • When using a CRI runtime, container logs and the writable container layers are part of local ephemeral storage and will count against the node’s and (if configured) namespace’s ephemeral-storage usage. That can produce surprising evictions or quota exhaustion when logs spike. (v1-32.docs.kubernetes.io)
  3. emptyDir accurate accounting needs filesystem project quotas and kubelet feature gates
    • Accurate tracking of emptyDir sizes (without expensive directory scans) relies on filesystem project quotas (XFS or specially-built ext4) and kubelet feature gates like LocalStorageCapacityIsolationFSQuotaMonitoring and LocalStorageCapacityIsolation. If these aren’t enabled and configured, accounting will be less accurate or absent. That makes namespace-level quotas unreliable for emptyDir volumes unless the node is prepared. (kubernetes.io)
  4. Some distributions have known behavior differences
    • Enterprise distributions (e.g., OpenShift) have documented cases where ephemeral-storage ResourceQuota enforcement can be incomplete unless you explicitly set requests on pods — the practical impacts are cluster-specific and worth checking for your platform. (access.redhat.com)

How to make ephemeral-storage quotas actually work — checklist

Minimal example: LimitRange + ResourceQuota to encourage correct behavior

apiVersion: v1
kind: LimitRange
metadata:
  name: default-storage-limits
  namespace: team-a
spec:
  limits:
  - type: Container
    defaultRequest:
      ephemeral-storage: "200Mi"
    default:
      ephemeral-storage: "1Gi"
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-storage-quota
  namespace: team-a
spec:
  hard:
    requests.ephemeral-storage: "50Gi"
    limits.ephemeral-storage: "60Gi"

Notes on the example

Edge cases and advanced considerations

A short operational recipe (quick checklist without commands)

Conclusion Ephemeral-storage is essential and useful — but its nature (local, transient, influenced by logs and runtime behavior) makes namespace-level quota enforcement trickier than CPU or memory. The good news: once you force pods to declare requests/limits (or inject them with LimitRange), prepare node filesystems for project quotas if you rely on emptyDir accuracy, and monitor both cluster and node metrics, you can get namespace-level ephemeral-storage quotas to behave reliably. Treat ephemeral-storage like a combination of parking rules and meter readers: set clear rules (requests/limits), give the system the right instruments (project quotas + kubelet feature gates), and monitor so you catch the parking violators before they fill the lot.

Sources and further reading