When a Kubernetes application has a performance problem, checking the Pod's resource configuration is usually one of the first things worth doing.
A Pod may have enough CPU but not enough memory. A container may be using much more CPU than expected. A request may be too low for accurate scheduling, or a limit may be restricting the workload during a traffic spike.
With Kubernetes 1.37, Pod-level resource configuration makes it even more important to understand the difference between the resources assigned to a Pod and the resources used by individual containers.
The good news is that Kubernetes already provides several commands for inspecting this information.
This article walks through the most useful commands, explains what each one tells you, and shows how to troubleshoot common resource problems.
Understanding Pod Resources First
Before checking resource usage, it helps to separate three concepts:
Resource request
Resource limit
Actual resource usage
They are related, but they are not the same thing.
For example:
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
This configuration describes the requested and maximum resources for the workload.
Actual usage can be very different:
CPU request: 500m
CPU limit: 1
Actual CPU: 220m
The application is currently using less CPU than its request and limit.
Understanding this difference prevents a lot of confusion when reading Kubernetes output.
Check Running Pods
The first command to run is:
kubectl get pods
For a specific namespace:
kubectl get pods -n production
You may see output similar to:
NAME READY STATUS RESTARTS AGE
orders-api-6d7f9c7d8b-abc12 2/2 Running 0 2h
orders-api-6d7f9c7d8b-def34 2/2 Running 1 2h
This tells you whether the Pods are running, but it does not show resource usage.
For that, you need additional commands.
Check Pod Resource Requests and Limits
Use:
kubectl describe pod orders-api-6d7f9c7d8b-abc12
The output contains information about the Pod and its containers.
Look for the container sections and their resource configuration.
For a Pod with multiple containers, this is useful because you can see how the resource configuration is distributed.
You can also inspect the complete object:
kubectl get pod orders-api-6d7f9c7d8b-abc12 -o yaml
This is particularly useful when you need to verify exactly what Kubernetes accepted.
Why -o yaml Is Useful
The YAML output lets you inspect the actual Pod specification rather than relying on the configuration file stored locally.
For example:
kubectl get pod orders-api-6d7f9c7d8b-abc12 -o yaml
You can search the output for:
resources
requests
limits
This is useful when a Deployment has been modified several times and you want to confirm what is actually running.
The live Pod specification is the source you should inspect when troubleshooting the running workload.
Check Current Resource Usage
If the cluster has the Kubernetes Metrics API available, you can use:
kubectl top pod
For a specific namespace:
kubectl top pod -n production
Example output:
NAME CPU(cores) MEMORY(bytes)
orders-api-6d7f9c7d8b-abc12 320m 410Mi
orders-api-6d7f9c7d8b-def34 280m 395Mi
This gives you a snapshot of current usage.
It does not replace long-term monitoring.
Resource usage changes over time, so a single kubectl top command cannot tell you what happened during yesterday's traffic spike.
Check Individual Container Usage
A Pod can contain multiple containers.
For example:
orders-api Pod
|
+-- application
|
+-- metrics-agent
You may want to know which container is consuming the CPU.
Depending on the available metrics support, you can use:
kubectl top pod orders-api-6d7f9c7d8b-abc12 --containers
This helps separate the resource usage of the containers inside the Pod.
For example:
POD NAME CPU(cores) MEMORY(bytes)
orders-api-... application 280m 350Mi
orders-api-... metrics-agent 40m 60Mi
Now the resource problem is easier to understand.
The Pod may be using:
CPU: 320m
Memory: 410Mi
but most of the usage comes from the application container.
Check Pod-Level Resource Configuration
When using Pod-level resources, inspect the Pod specification directly.
For example:
kubectl get pod orders-api-6d7f9c7d8b-abc12 -o yaml
Look for the Pod specification's resource configuration.
A simplified configuration may look like:
spec:
resources:
requests:
cpu: "1"
memory: "512Mi"
limits:
cpu: "2"
memory: "1Gi"
This tells you the resource budget defined at the Pod level.
You should also inspect the individual containers because a Pod can contain additional container-level resource configuration.
Pod-Level Resources vs Actual Usage
Consider this configuration:
spec:
resources:
requests:
cpu: "1"
memory: "512Mi"
limits:
cpu: "2"
memory: "1Gi"
Now suppose:
Actual CPU: 650m
Actual memory: 620Mi
The CPU usage is below the configured CPU limit.
Memory usage is also below the configured memory limit.
However, memory is getting closer to the configured maximum.
That is worth monitoring.
A single measurement does not mean the Pod has a memory problem, but a sustained upward trend may require investigation.
Check Resource Usage Across a Namespace
For a quick view:
kubectl top pods -n production
This can help identify Pods using unusually high CPU or memory.
For example:
NAME CPU(cores) MEMORY(bytes)
api-1 100m 250Mi
api-2 120m 260Mi
worker-1 900m 800Mi
worker-2 850m 780Mi
The worker Pods are using considerably more resources than the API Pods.
That does not automatically mean something is wrong.
The worker may simply be doing more work.
The command gives you a starting point for investigation.
Check the Node Running the Pod
Pod resource problems can sometimes be related to node capacity.
First find the node:
kubectl get pod orders-api-6d7f9c7d8b-abc12 -o wide
You may see:
NAME READY STATUS NODE
orders-api 2/2 Running worker-node-01
Then inspect the node:
kubectl describe node worker-node-01
Look at:
Allocatable CPU
Allocatable memory
Requested resources
Resource limits
Conditions
Memory pressure
Disk pressure
This gives you information about the environment hosting the Pod.
Resource Requests and Scheduling
Suppose a Pod specifies:
requests:
cpu: "2"
memory: "1Gi"
Kubernetes needs to find a node capable of satisfying that request.
This is why requests should reflect realistic resource requirements.
If requests are set too high, the scheduler may have difficulty placing Pods even when actual application usage is low.
For example:
Actual usage: 200m CPU
Request: 2 CPU
The application may not currently need 2 CPUs, but the scheduler considers the configured request.
This can lead to inefficient cluster utilization.
Check Events
When a Pod cannot start or has resource-related problems, inspect events:
kubectl describe pod <pod-name>
Near the bottom of the output, look for:
Events
Events can provide useful information about:
Scheduling failures
Image problems
Container startup failures
Evictions
Resource-related conditions
Events are often the first place to look when a Pod is not behaving as expected.
Check for OOMKilled
Memory problems deserve special attention.
Run:
kubectl describe pod <pod-name>
Look at the container status.
You may see information indicating that a container was terminated because of an out-of-memory condition.
You can also inspect the previous container state:
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[*].lastState}'
If a container is repeatedly being killed for memory usage, increasing the limit may be one possible solution, but it should not be the first response.
First determine why memory usage is increasing.
Possible causes include:
Memory leaks
Larger-than-expected workloads
Unbounded caches
Large buffers
Application configuration
Unexpected traffic
Incorrect resource sizing
Check CPU Throttling Carefully
CPU limits behave differently from memory limits.
When a workload reaches its CPU limit, the container can be throttled.
A Pod may therefore appear healthy while experiencing reduced CPU availability.
If an application suddenly becomes slower during high traffic, check:
CPU usage
CPU limit
CPU throttling
Request latency
Do not conclude that CPU is the problem just because usage is high.
A high CPU value can simply mean the application is actively processing work.
The important question is whether the CPU limit is restricting useful work.
Inspect a Deployment
Pods are usually managed by Deployments.
Check the Deployment:
kubectl get deployment orders-api -n production -o yaml
The resource configuration is normally defined inside the Pod template.
For example:
spec:
template:
spec:
containers:
- name: application
image: orders-api:1.0
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"
If you are using Pod-level resources, inspect the corresponding Pod specification as well.
This helps determine whether the configuration you expect is actually being applied to new Pods.
Why Checking the Deployment Is Important
Suppose you manually inspect a running Pod and find:
CPU limit: 1
You then update your Deployment to:
CPU limit: 2
The existing Pod does not automatically become a new Pod with every change to the Deployment template.
A Deployment normally creates replacement Pods when its Pod template changes.
So after changing resource configuration, verify the new Pods.
Use:
kubectl rollout status deployment/orders-api
Then:
kubectl get pods -n production
Finally inspect the new Pod:
kubectl describe pod <new-pod-name>
A Practical Troubleshooting Workflow
When an application reports high CPU or memory usage, use a simple sequence.
Step 1: Find the Pod
kubectl get pods -n production
Step 2: Check Current Usage
kubectl top pod -n production
Step 3: Inspect the Pod
kubectl describe pod <pod-name> -n production
Step 4: Check Resource Configuration
kubectl get pod <pod-name> -n production -o yaml
Step 5: Check the Node
kubectl get pod <pod-name> -n production -o wide
kubectl describe node <node-name>
Step 6: Check Application Logs
kubectl logs <pod-name> -n production
For a specific container:
kubectl logs <pod-name> -c application -n production
Step 7: Compare With Historical Metrics
A single snapshot is not enough.
Use your monitoring system to determine whether the behavior is:
Normal
Temporary spike
Sustained increase
Resource leak
Capacity problem
Common Mistakes
Looking Only at CPU
A Pod can have low CPU usage and still have a serious memory problem.
Always check both CPU and memory.
Treating kubectl top as Historical Data
kubectl top is useful for current usage.
It is not a replacement for long-term metrics.
Checking Only the Pod
The node may also be under pressure.
Always consider the relationship between Pod resources and node capacity.
Increasing Limits Without Investigation
If memory usage keeps increasing, simply increasing the limit may delay the problem rather than solve it.
Forgetting Multiple Containers
A Pod-level problem may be caused by one specific container.
Check individual container usage when the Pod contains sidecars.
Best Practices
Use Requests Based on Real Usage
Collect application metrics before choosing resource requests.
Set Limits Carefully
Limits should protect the cluster without unnecessarily restricting the application.
Monitor Trends
Use monitoring dashboards to identify changes over time.
Check Both Pod and Container Levels
A Pod can look healthy overall while one container is consuming most of its resources.
Inspect Nodes During Resource Incidents
Cluster-level capacity matters.
Keep Resource Configuration in Version Control
Resource settings should normally be managed with the same deployment configuration as the application.
A Useful Resource Checklist
When investigating a Pod, check:
Check | Command |
|---|---|
Pod status |
|
Detailed Pod information |
|
Current resource usage |
|
Container usage |
|
Full Pod configuration |
|
Node placement |
|
Node resources |
|
Application logs |
|
Deployment configuration |
|
Deployment rollout |
|
The exact availability of some resource metrics commands depends on the cluster's metrics setup.
How to Interpret What You Find
Suppose you find:
Pod CPU limit: 2 CPU
Pod CPU usage: 700m
Pod memory limit: 1Gi
Pod memory usage: 920Mi
The CPU does not currently appear close to its configured limit.
Memory deserves more attention because usage is relatively close to the configured limit.
Now check historical metrics.
If memory has remained around 900Mi for weeks, the configuration may simply reflect the application's normal workload.
If memory has increased from 300Mi to 920Mi over a short period, investigate the application.
This is why resource troubleshooting should combine configuration, current usage, and historical behavior.
Summary
Checking Pod resources in Kubernetes is more than running a single command. You need to look at the resource configuration, current usage, individual containers, node capacity, and application behavior together.
Start with kubectl get pods and kubectl top pod to understand what is currently running and how much CPU and memory it is using. Then use kubectl describe pod and kubectl get pod -o yaml to inspect the actual configuration.
For multi-container Pods, check individual container usage as well. If the Pod is experiencing resource pressure, inspect the node and review historical monitoring data before changing requests or limits.
Kubernetes 1.37's Pod-level resource model makes it especially useful to understand the difference between the Pod's overall resource configuration and the usage of each container inside it.
The most reliable troubleshooting approach is to combine Kubernetes commands with application-level monitoring. A resource value by itself does not explain a performance problem. The useful information comes from comparing what the application requested, what it is allowed to use, what it is actually using, and how those values change over time.

Join the conversation! Your thoughts help the community grow.