Diagnosing Docker Container High CPU Usage on Linux and Windows

Learn to diagnose and stop a single Docker container from consuming excessive CPU on Linux and Windows hosts, using process-level inspection and resource limits.

Rao Aadil, India 5 min read

Confirm High CPU Usage at the Host Level

Start at the host: is it actually under CPU pressure? On Linux, run top or htop. On Windows, open Task Manager with Ctrl+Shift+Esc and check the CPU column, or use PowerShell:

Get-Counter '\Processor(_Total)\% Processor Time'

A misbehaving container on Linux shows up as a process such as dockerd or the container's main process consuming CPU, because containers use cgroups. Docker Desktop on Windows runs containers in a VM (WSL2 or Hyper-V), so you might see vmmem or Docker Desktop.exe spike instead. That's expected for that architecture.

For a per-container breakdown, docker stats works on both Linux and Windows hosts:

docker stats --no-stream

Look for a container with a high CPU% value. --no-stream prints one snapshot instead of a live updating stream.

Doing this with brynko devOps Agent

Inspect containers, read logs, check stats, restart services and run Compose stacks, just by describing what you want.

“why does this container keep restarting”

It reads the real state of the server before it says anything, shows you the exact command, and waits for your approval. Windows and Linux, over the SSH access you already have.

Download for WindowsSee what else it does

Identify the Container and Process Responsible

By default, docker stats output is not sorted by CPU. On Linux, pipe it to sort after stripping the percent sign:

docker stats --no-stream --format "{{.CPUPerc}} {{.Name}}" | sed 's/%//' | sort -nr

On Windows PowerShell, the equivalent is:

docker stats --no-stream --format "{{.CPUPerc}} {{.Name}}" | ForEach-Object {
    $cpu, $name = $_ -split ' ', 2
    [PSCustomObject]@{ CPU = [double]$cpu.Trim('%'); Name = $name }
} | Sort-Object CPU -Descending | Format-Table

You get the container name and CPU percentage in descending order.

With the suspect container identified, inspect the processes inside it. For Linux containers, run either:

docker top <container>

or

docker exec <container> ps aux

docker top shows host PIDs, which helps with mapping to the host later. For Windows containers, run:

docker exec <container> cmd /c tasklist

or

docker exec <container> powershell Get-Process

These commands assume the container OS matches. If you're running a Linux container on Docker Desktop with WSL2, use the Linux commands, not Windows commands.

To map a container process to a host process on Linux, first get the container's main process host PID:

docker inspect --format '{{.State.Pid}}' <container>

Then use ps -p <pid> -o pid,ppid,%cpu,%mem,cmd on the host to see that process. For child processes, docker top already lists host PIDs. On Windows with Hyper-V isolation, mapping is less direct; the container runs in a separate VM. For WSL2, use wsl --list --verbose to find the distribution name, then wsl -d <distro> top to view processes inside the WSL2 VM.

An AI agent for Docker operations can accelerate this step: ask it 'which container is eating all the memory' or 'why does this container keep restarting' to get a breakdown of resource usage and logs without manually running each command.

Immediate Mitigation: Stop the CPU Spike

When the container is causing an outage, restart it to stop the runaway process. The command is the same on Linux and Windows:

docker restart <container>

A restart terminates the current container and starts a new one. It causes brief downtime and loses any state not stored in a volume or external service. If the container must stay stopped while you investigate, use:

docker stop <container>

docker pause <container> pauses processes without terminating them on Linux, but it is not supported for Windows containers.

You can apply a CPU limit to a running container without a restart. This works on Linux containers and on Windows containers with Hyper-V isolation (Docker Engine 19.03 or newer):

docker update --cpus 2 <container>

That limits the container to two CPU cores. For Docker Desktop with WSL2 running Linux containers, the limit applies to the Linux VM's CPU allocation to that container. docker update takes effect immediately without a restart.

Find and Fix the Root Cause Inside the Container

Stopping the spike is only the first step. Check recent logs for errors or abnormal activity:

docker logs --tail 200 <container>

Logs work on both Linux and Windows hosts. If they don't show enough, run diagnostics inside the container. For Linux containers:

docker exec -it <container> top
docker exec <container> ps aux

If the container has strace or perf installed, attach to a specific process ID from inside:

docker exec <container> sh -c 'strace -p <pid>'
docker exec <container> perf top

For Windows containers, use PowerShell performance counters:

docker exec <container> powershell Get-Counter '\Process(*)\% Processor Time'

For .NET applications, dotnet-trace can collect a trace from inside the container if it's installed.

Common culprits include infinite loops, garbage collection thrashing in Java or .NET applications, busy-waiting on locks or I/O, misconfigured thread pools, and runaway background jobs. If the high CPU comes from application code, fix the bug or optimize the algorithm. If it comes from configuration, adjust environment variables or configuration files to reduce worker count or thread pool size. Automated diagnostics can summarize findings, but code fixes need human judgment.

Prevent Future High CPU Occurrences

Set resource limits before a container starts. In a Docker Compose file (Compose v2), add a cpus key under the service:

services:
  myapp:
    image: myapp:latest
    cpus: 2

Swarm mode uses deploy.resources.limits.cpus instead:

services:
  myapp:
    image: myapp:latest
    deploy:
      resources:
        limits:
          cpus: '2.0'

When running a container manually, use --cpus to cap CPU and --cpu-shares to set a relative weight (not a hard limit) among containers:

docker run --cpus 2 --cpu-shares 512 myimage

Both flags work on Linux containers and Windows containers with Hyper-V isolation.

Health checks catch unhealthy containers early. In a Dockerfile:

HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost/ || exit 1

Or in Compose:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost/"]
  interval: 30s
  timeout: 3s

Continuous monitoring closes the loop. cAdvisor and Prometheus can scrape Docker stats and alert on sustained high CPU. Docker Desktop includes built-in resource usage graphs for containers on Windows and macOS.

Related reading

Stop Docker Container High CPU Usage

Use the steps in this guide to identify the offending process, apply immediate limits, and prevent recurrence with proper resource controls.

An AI teammate that builds, runs, fixes, deploys and operates your software, on your machine and on your servers. It reads the real state of your systems, shows you every command before it runs, and never touches production without your approval.

Works with Docker Docker Compose nginx IIS Tomcat MySQL / MariaDB PostgreSQL Redis Linux servers Windows servers AWS Jenkins Let's Encrypt Node.js Python Java .NET Go PHP
  • Every change asks first, and shows you the exact command or diff before it runs.
  • File edits are snapshotted and reversible. Deleted folders are archived, not removed.
  • Private key material never reaches the model, under any setting.
brynko devOps Agent
Docker

the checkout container keeps restarting

read container state checked health check listed ports

It restarts every 40 seconds, and it is the health check failing rather than the app. The check calls /healthz on port 8080, but the app is listening on 3000, so it never passes and Docker keeps killing it.

fix it

one line in compose restarted watched 5 minutes

Done. I corrected the health check port and restarted the service. It has stayed up since, and the check is passing.

Fixed · container healthy

Free download for Windows. 300 free credits on signup, no card, no subscription.

Questions

Common questions

How do I find which Docker container is using high CPU?
Run `docker stats --no-stream` to see CPU% for all running containers. Sort the output by CPU% to identify the container with the highest usage, then inspect it further with `docker top` or `docker logs`.
What is the normal CPU usage for a Docker container?
There is no universal normal value; it depends entirely on the application workload. An idle container typically shows near 0% CPU, while a busy service might legitimately use multiple cores. Sustained usage above 80% for long periods often warrants investigation.
How can I see the processes inside a container and their CPU usage?
For Linux containers, use `docker exec <container> ps aux` or `docker top <container>`. For Windows containers, use `docker exec <container> powershell Get-Process` or `cmd /c tasklist`. Some containers may require installing process utilities first.
Can I limit the CPU usage of a running container without restarting it?
Yes, you can use `docker update --cpus <value> <container>` on Linux and on Windows with Hyper-V isolation. This applies the limit immediately without restarting the container, though the effect may vary depending on the backend.
Why is my container using 100% CPU after a restart?
It could be an application bug, an infinite loop, missing configuration, or a resource limit that was not reapplied after the restart. Inspect the container logs and processes with `docker logs --tail 200 <container>` and `docker top <container>` to identify the cause.
How do I monitor Docker CPU usage over time to catch spikes?
Use monitoring tools like cAdvisor or Prometheus to collect and alert on Docker stats, or use Docker Desktop's built-in resource usage graphs. You can also sample `docker stats --no-stream` periodically via a cron job or scheduled task.
What is the difference between host CPU usage and container CPU usage on Docker Desktop for Windows?
Docker Desktop runs containers inside a Linux VM (WSL2 or Hyper-V). The host may show high CPU for the VM process (`vmmem` or `Docker Desktop.exe`), while `docker stats` reports CPU usage inside the VM as seen by the container. The two values can differ because of virtualization overhead.

Keep reading