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:

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:

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:

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

kubectl get pods

Detailed Pod information

kubectl describe pod

Current resource usage

kubectl top pod

Container usage

kubectl top pod --containers

Full Pod configuration

kubectl get pod -o yaml

Node placement

kubectl get pod -o wide

Node resources

kubectl describe node

Application logs

kubectl logs

Deployment configuration

kubectl get deployment -o yaml

Deployment rollout

kubectl rollout status

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.