✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Kubernetes Storage ResourceQuota Management

Kubernetes Storage ResourceQuota Management ensures efficient resource allocation and prevents overconsumption in containerized environments.

Kubernetes Storage ResourceQuota Management is the practice of bounding the total amount of persistent storage a namespace's PersistentVolumeClaims may collectively request, using the requests.storage quota dimension and its per-storage-class variants, ensuring that storage consumption — often the most expensive and slowest-to-reclaim resource dimension in a cluster — is governed with the same namespace-level discipline applied to CPU and memory. Storage quota differs from compute quota in an important practical way: storage is typically provisioned once per claim and persists for a long, often indefinite duration, meaning storage quota violations tend to accumulate slowly through claim creation rather than fluctuating rapidly the way CPU and memory consumption can as Pods restart.

Because storage capacity is frequently the more expensive and operationally sensitive resource dimension (particularly for high-performance storage classes), storage quota management often receives distinct governance attention separate from the more routinely adjusted compute quotas.


Basic Storage Quota

Aggregate requests.storage

apiVersion: v1
kind: ResourceQuota
metadata:
  name: codartium-storage-quota
spec:
  hard:
    requests.storage: "500Gi"

This bounds the sum of every PersistentVolumeClaim's requested storage size within the namespace, regardless of which storage class is used, providing a simple, single ceiling on total storage footprint.


Per-Storage-Class Quotas

Differentiating Tiers of Storage

Clusters offering multiple storage classes (a fast, expensive SSD tier and a slower, cheaper HDD or object-backed tier) commonly apply separate quota dimensions per class, named <storage-class-name>.storageclass.storage.k8s.io/requests.storage, allowing more expensive storage to be governed more tightly than cheaper alternatives.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: codartium-tiered-storage-quota
spec:
  hard:
    codartium-ssd.storageclass.storage.k8s.io/requests.storage: "100Gi"
    codartium-standard.storageclass.storage.k8s.io/requests.storage: "1000Gi"

This allows a team broad latitude to use standard storage liberally while imposing a much tighter ceiling on the premium tier, reflecting its higher cost or scarcity.


Object Count Quotas for PVCs

Bounding the Number of Claims

Independent of aggregate size, persistentvolumeclaims (and its per-storage-class equivalent) bounds the total number of claim objects a namespace may create, which is a useful complementary control against a namespace creating an excessive number of small claims that might otherwise stay within a size-based quota while still straining storage provisioner throughput or API object counts.

spec:
  hard:
    persistentvolumeclaims: "20"
    codartium-ssd.storageclass.storage.k8s.io/persistentvolumeclaims: "5"

Storage Quota Enforcement Nuances

Enforced Against Requested, Not Actual, Size

Storage quota is evaluated against the requests.storage value declared on the PersistentVolumeClaim, not the volume's actual current data usage — a claim requesting 100Gi consumes the full 100Gi against quota even if the application currently stores only a few gigabytes of actual data, since Kubernetes provisions (and quota-accounts for) the full requested size upfront.

Long-Lived Consumption

Because storage claims typically persist far longer than the Pods that use them (surviving Pod restarts, and in many cases surviving even the deletion of the workload that originally created them, if not explicitly cleaned up), storage quota consumption tends to accumulate and remain elevated over time unless claims are actively deleted — a namespace's storage quota utilization is a much stickier, slower-changing signal than its compute quota utilization.

kubectl get pvc -n codartium-team
kubectl describe resourcequota codartium-storage-quota -n codartium-team

Reclaiming Storage Quota

Identifying Orphaned or Unused Claims

Because storage quota consumption persists even after a workload is deleted (if the claim itself was not also deleted), periodic audits identifying PersistentVolumeClaims no longer referenced by any active Pod are a common practice for reclaiming quota headroom that would otherwise silently remain consumed indefinitely.

kubectl get pvc -n codartium-team -o json | \
  jq -r '.items[] | select(.metadata.name as $n | ([inputs.spec.volumes[]?.persistentVolumeClaim?.claimName] | index($n)) == null) | .metadata.name'

Coordinating Deletion with Reclaim Policy

Deleting a PersistentVolumeClaim to reclaim storage quota interacts with the underlying PersistentVolume's reclaim policy — a Delete policy actually frees the underlying storage (and its quota consumption) upon claim deletion, while a Retain policy leaves the underlying volume (and, depending on configuration, its accounted consumption) in place even after the claim is removed, requiring a separate manual cleanup step to fully reclaim quota headroom.


Example

apiVersion: v1
kind: ResourceQuota
metadata:
  name: codartium-storage-example
  namespace: codartium-team
spec:
  hard:
    requests.storage: "300Gi"
    persistentvolumeclaims: "15"
    codartium-ssd.storageclass.storage.k8s.io/requests.storage: "50Gi"