# Missing CPU/Memory Requests

> A container without CPU and memory requests gives the scheduler nothing to place it with. ZopNight reads the pod spec across Deployments, StatefulSets and DaemonSets (3 workload kinds), and names every offending container. There is no metric here; it is a pure configuration read.

Source: https://zop.dev/integrations/kubernetes/recommendations/missing-cpu-memory-requests
Updated: 2026-08-19

---

## Requests are what the scheduler actually uses

A request is a reservation. The scheduler sums the requests already placed on each node and puts
your pod where the remainder fits. A container with no request contributes zero to that sum, so
the scheduler treats it as free and will keep packing the node.

Limits are a different thing entirely, a ceiling enforced at runtime. Setting limits without
requests is common and does not help placement at all.

## What goes wrong without them

**Nodes get oversubscribed.** Pods land wherever there is nominal room, then contend for CPU and
memory that was never reserved.

**OOM kills arrive under load.** A node running several request-less containers has no accounting
for what they will actually consume, so memory pressure appears suddenly rather than being
prevented at scheduling time.

**Eviction order works against you.** Kubernetes assigns Quality of Service from requests and
limits. A pod with neither is `BestEffort`, the first class evicted when a node comes under
pressure, regardless of how important the workload is.

That last point is the one teams find surprising: the workload you cared most about is the one
the kubelet kills first, purely because nobody set a request on it.

## No metric, no window

This rule reads the discovered pod spec and nothing else. There is no utilisation threshold and
no lookback: a container either declares both requests or it does not.

It abstains when the workload metadata carries no containers at all, and it requires an explicit
present value: a missing field is treated as missing, not as zero.

## Filtering containers with empty requests fields

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

## Setting sensible values

Run the Vertical Pod Autoscaler in recommend mode for a week and read its suggestions rather
than guessing. Then add a `LimitRange` to the namespace so future workloads inherit defaults
instead of shipping with nothing.
