Skip to main content
reliability · kubernetes

Workloads with no CPU or memory limits set

resource types
3
rule IDs covered
9
severity
medium

What does ZopNight detect here?

A container without limits can consume whatever the node has. ZopNight reads the pod spec across 3 workload kinds and names each offending container. Note the asymmetry: a missing memory limit risks taking the node down, while a missing CPU limit is often the better choice.

Signal and threshold

How ZopNight evaluates Workloads with no CPU or memory limits set.
Field Value
Rule IDsRC-1703 · RC-1803 · RC-1903 · RC-1704 · RC-1804 · RC-1904 · RC-1705 · RC-1805 · RC-1905
Categoryreliability
Severitymedium
Metricnone — pure configuration read
Sourceinternal/rules/k8s/workload_no_limits.go

CPU and memory limits are not the same decision

They are usually discussed together and they behave completely differently under pressure. This is the single most useful thing to understand about this finding.

Memory is incompressible. A container exceeding available memory cannot be slowed down. It gets OOM-killed. Without a limit, one leaking process can consume the node’s memory and take neighbouring pods with it.

CPU is compressible. A container exceeding its CPU limit is throttled, not killed. It simply runs slower.

Why a missing CPU limit is often correct

CPU limits cause throttling even when the node has idle capacity. A service limited to 500m gets throttled at 500m regardless of whether the node is 90% idle. Latency spikes for no benefit to anybody.

Many production Kubernetes practitioners deliberately set CPU requests and omit CPU limits, letting workloads burst into spare capacity while requests guarantee the floor.

So treat the CPU half of this finding as a prompt to decide, not a defect to fix. The memory half is closer to a genuine defect.

What limits do give you

Quality of Service. A pod with requests equal to limits on both resources is Guaranteed, the last class evicted under node pressure. Requests without limits is Burstable. Neither is BestEffort, evicted first.

If a workload must survive node pressure, Guaranteed is the only class that gets you there.

No metric here

This is a configuration read. There is no utilisation threshold and no lookback window: a container declares limits or it does not. The rule abstains when the workload metadata carries no containers.

Filtering containers with no memory limit

Terminal window
kubectl get deploy,statefulset,daemonset -A -o json | jq -r '
.items[] | . as $w | .spec.template.spec.containers[]
| select((.resources.limits.memory // "") == "")
| "\($w.kind) \($w.metadata.namespace)/\($w.metadata.name): \(.name)"'

Filtering on memory alone surfaces the half that actually threatens the node.

Where to set them

A namespace LimitRange applies defaults to anything that does not declare its own, which fixes the whole backlog at once and stops new workloads arriving without them.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·