Full lesson
Explore the full explanation, examples, and visuals at your own pace.
deployment.yaml, CPU style copied into memory
In Kubernetes, memory 500m asks for half a byte. The developer set cpu to 500m, which correctly means half a core. Then they copied that same style into the memory lines, for both requests and limits. The suffix m means one thousandth, so memory gets a nearly empty budget.
resources:
requests:
cpu: 500m
memory: 500m
limits:
cpu: 500m
memory: 500mAccepted at apply, fails at container start
When the developer runs apply, the API server only checks that 500m is a valid quantity. It is, so the pod is created and nothing complains. Later, the kubelet, the agent on each node, asks the runtime, the software that actually starts containers, to launch it. With a limit near zero, the container fails or gets killed, and the kubelet reports that back.
Kubernetes quantity units
Here's a quick reference. The suffix m means milli, one thousandth. Mi and Gi are binary, powers of 1024, so one Mi is 1,048,576 bytes. M and G are decimal, powers of 1000. These suffixes scale the number the same way for any resource.
- m = milli, one thousandth
- Mi, Gi: binary, 1Mi = 1,048,576 bytes
- M, G: decimal, 1M = 1,000,000 bytes
Same suffix, different resource
Look at the two sides. For CPU, 500m means 0.5, half a core, which is a sensible request. For memory, the very same 500m means 0.5 bytes, a tiny fraction of one byte. The suffix is just a scale. It doesn't know which resource it's describing.
Three memory values side by side
Here are three memory values on one chart. The 500m bar is invisible, because it's half a byte. 500M is 500 million bytes, so 500 megabytes. 500Mi is about 524 million bytes, a bit larger. Changing one letter changes the scale enormously.
Chart values
| Value written | Megabytes (MB) |
|---|---|
| 500m | 5e-7 |
| 500M | 500 |
| 500Mi | 524.288 |
Illustrative: a tight limit and the M vs Mi gap
There's a smaller gotcha too. 500Mi is about 4.9 percent larger than 500M. Say an app peaks at 510 megabytes, as an illustrative number. A 500M limit sits below that peak, so the container gets killed. A 500Mi limit, about 524 megabytes, sits above it, so the app survives.
Chart values
| Label | Megabytes (MB) |
|---|---|
| Limit 500M | 500 |
| App peak | 510 |
| Limit 500Mi | 524.3 |
Failure varies by runtime and environment
What you actually see depends on your runtime and environment. Some reject the tiny limit when creating the container. Others start it, then it's OOMKilled, meaning out of memory. As kubelet keeps restarting it, the pod ends up in CrashLoopBackOff.
- Container creation error
- OOMKilled right after start
- CrashLoopBackOff as kubelet retries
Step 1: check state and events (illustrative output)
Start with kubectl describe pod web. It shows the container's current state, why it last terminated, and recent events. Here, that's CrashLoopBackOff after OOMKilled. Then the Limits section shows memory: 500m. That's the clue. This output is illustrative, and the exact reasons may differ on your cluster.
$ kubectl describe pod web
app:
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: OOMKilled
Limits:
memory: 500m
Events:
Warning BackOff restarting failed containerStep 2: read back what was stored, then fix
To confirm, run kubectl get pod web with dash o yaml. That prints exactly what the cluster stored, and under limits you'll see memory: 500m, kept as written. Kubernetes never corrected it. The fix lives in your manifest: change it to 512Mi, then apply it again.
$ kubectl get pod web -o yaml
resources:
limits:
cpu: 500m
memory: 500m # stored as written
# fix in the manifest:
memory: 512MiPrevent it before the cluster
You can stop this before it reaches the cluster. Standardize on Mi or Gi for memory. Then add a CI lint step that flags milli units on memory, or an admission policy tool that rejects suspicious values before apply. No specific tool is required.
- Use Mi or Gi for memory consistently
- CI checks flag milli units on memory
- Policy tools reject suspicious memory values
The suffix sets the scale; m means thousandth for everything.
The suffix sets the scale; m means thousandth for everything. So write memory in Mi or Gi, and when a pod dies instantly, read back its resources.
