A registered rule that deliberately emits nothing today
What does ZopNight detect here?
No memory rightsizing recommendation is produced by this rule at all. The 1 signal it previously used, an HPA `ScalingLimited` condition, measures replica count, not per-container memory, and acting on it risks OOM kills. Abstaining was chosen over shipping an unsound recommendation.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1772 · RC-1872 · RC-1972 · RC-1773 · RC-1873 · RC-1973 |
| Category | rightsizing |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | internal/rules/k8s/memory_over_provisioned.go |
Where it applies
Stated plainly: this rule abstains
The rule is registered so the catalogue stays stable across releases, and it returns no recommendation for any workload. That is the current, intended behaviour: not a bug, not a coverage gap awaiting data, and not something a permission or metric on your side will change.
Publishing that is more useful than implying a capability that does not exist.
The signal it used to run on, and why it was wrong
It keyed off an HPA reporting ScalingLimited with reason TooFewReplicas, the autoscaler
wanting to scale below minReplicas.
That is a statement about replica count. It says the workload as a whole has more copies than demand justifies. It says nothing whatsoever about whether each pod’s per-container memory request exceeds that container’s working set.
Both can be true at once in either direction. A workload can be replica-over-provisioned while its memory requests are correctly sized, or even too small. Cutting memory requests on that evidence is a coin flip dressed as a recommendation.
Why the consequence is worse than for CPU
Memory is incompressible. There is no throttling equivalent.
Set a memory request below the actual working set and the kernel OOM-kills the container. On a StatefulSet backing PersistentVolumes that means a data-path stall and eviction, on a pod whose identity and storage are pinned to its ordinal. The cost of being wrong is not a slow service. It is a restarted one, possibly mid-write.
Under evidence-sufficiency, an action whose failure mode is destructive requires an authoritative observation. Nothing available today provides one.
What would make it emit
A memory-utilization producer: working-set p95 over a real observation window, from VPA
recommendations or a metrics pipeline that retains a series. metrics-server cannot supply this, because
it exposes point-in-time snapshots, which is exactly why the HPA-condition workaround was
attempted in the first place.
Until such a producer is wired through, the rule stays silent. Re-keying it off
hasConditionReason for memory was considered and explicitly rejected.
Checking your own memory headroom meanwhile
VPA in recommendation-only mode is the practical substitute, since it observes and suggests without applying:
kubectl get vpa -A -o json | jq -r ' .items[] | .metadata.namespace + "/" + .metadata.name + "\t" + ([.status.recommendation.containerRecommendations[]? | .containerName + ":" + .target.memory] | join(" "))'Compare target.memory against the request in the pod spec, and treat anything within roughly
20% as correctly sized.