# ResourceQuota Near Limit

> Warns when any resource in a ResourceQuota sits between 85% and 100% of its hard limit, before rollouts and scale-ups start failing.

Source: https://zop.dev/integrations/kubernetes/recommendations/resourcequota-near-limit

---

## Headroom disappears faster than usage suggests

Steady-state usage is not the peak a quota has to absorb. Two routine events briefly need more
than the namespace normally holds:

- **Rolling updates.** A Deployment on the default `RollingUpdate` strategy may run up to 25%
  more pods than desired while it swaps versions, according to the
  [Deployments documentation](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/).
  Those surge pods count against `pods`, `requests.cpu` and `requests.memory` like any other.
- **Autoscaling.** An HPA adding replicas during a traffic spike needs quota at the worst
  possible moment.

When the extra pods do not fit, the API server refuses them with 403 Forbidden, as described in
the [resource quotas documentation](https://kubernetes.io/docs/concepts/policy/resource-quotas/).
A namespace at 90% of its pod count can therefore run fine for weeks and then fail its next
release.

## Measuring how close each quota is

```bash
kubectl get resourcequota -A \
  -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,USED:.status.used,HARD:.status.hard
```

`kubectl describe resourcequota -n <namespace>` prints the same data as a table per resource,
which is easier to read for CPU and memory values with units.

## Why 85% is the trigger

ZopNight compares used with hard for every resource that the quota reports on both sides,
converting quantities such as `500m` or `8Gi` so the ratio is meaningful. It takes the highest
ratio in the quota and fires when that ratio is at least 0.85 and below 1.0. The finding quotes the
percentage it found, so a quota at 92% says 92%. There is no time window: the ratio is recomputed
each evaluation, and a quota that drops below 85% clears on its own.

As a worked example, a quota with `pods: "20"` and 18 pods running is at 90%. A four-replica
Deployment in that namespace needs one surge pod to roll, which takes it to 19; two such rollouts
at once would need 20, and a third would be refused.

## When it stays quiet

At 100% or above, the quota is reported by
[ResourceQuota exhausted](https://zop.dev/integrations/kubernetes/recommendations/resourcequota-exhausted) rather
than here, so the two findings never overlap. Entries with a hard limit of zero, entries with no
matching usage value and values that cannot be parsed are left out of the ratio.

## An early warning, not a saving

The recommendation carries no savings estimate. It exists to give the namespace owner time to act
before a deploy is blocked.

## Restoring headroom

1. Identify the resource near its cap from the `describe` output.
2. Decide whether usage is legitimate growth or leftovers such as failed Jobs and idle
   Deployments, and clean up the leftovers first.
3. If growth is real, raise `spec.hard` for that resource with enough margin for surge pods and
   the HPA's `maxReplicas`.
4. Revisit the quota after the next release to confirm the rollout fit comfortably.
