Home / Alt manpages / docker-container-stats(1)

  • docker-container-stats(1)
  • User command
  • linux

Read Live Container CPU and Memory with docker stats

Something on the host is chewing CPU or memory, and docker container stats (also docker stats) tells you which container it is. You will read live CPU, memory, network, block I/O and process counts, then take a single sample and print a compact table for one named container. Allow about ten minutes.

  • You need: a working Docker CLI and access to a Docker daemon with at least one container to inspect.
  • Versions: the examples use Docker CLI 29.8.1, installed here from docker-ce-cli.
  • Safety: read-only. It does not restart, stop, pause or reconfigure containers, and it normally needs no sudo.

If your Docker setup restricts access to the daemon socket, fix that access according to your host policy. Do not bolt elevated privileges onto every monitoring command.

1. Check the command and the daemon

Confirm which executable you will run, then list the containers that the current Docker context can see:

$ docker version --format '{{.Client.Version}}'
29.8.1
$ docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Status}}'
CONTAINER ID   NAMES          STATUS
abc123def456   example-web    Up 12 minutes

The container ID and name in your output will differ. Keep one of them for the next step.

Tip

If the command says it cannot connect to the daemon, check docker context show and the daemon service before troubleshooting statistics. Do not start or restart a service just because the output is empty: first establish whether you are using the intended context.

Checkpoint

You have a running container name or ID, and docker ps completed successfully.

2. Watch all running containers

Run the command with no container arguments:

$ docker container stats
CONTAINER ID   NAME          CPU %   MEM USAGE / LIMIT   MEM %   NET I/O        BLOCK I/O     PIDS
abc123def456   example-web   0.02%   18.4MiB / 2GiB      0.90%   12.1kB / 0B    0B / 0B       6

The display refreshes as a live stream until you press Ctrl-C. Read the columns like this:

  • CPU and memory percentages are percentages of the host resources reported by Docker. Memory usage is shown against the container's limit.
  • The memory figure excludes cache on Linux. The CLI subtracts cache usage, so do not compare this column blindly with a raw cgroup total or with the Docker stats API.
  • NET I/O is received and transmitted network data.
  • BLOCK I/O is data read from and written to block devices.
  • PIDS counts processes and kernel threads created by the container. A high value can therefore indicate thread creation even when a process listing looks small.

For one stable sample, interrupt the stream and use --no-stream:

$ docker container stats --no-stream example-web
CONTAINER ID   NAME          CPU %   MEM USAGE / LIMIT   MEM %   NET I/O        BLOCK I/O     PIDS
abc123def456   example-web   0.02%   18.4MiB / 2GiB      0.90%   12.1kB / 0B    0B / 0B       6

The exact values change between runs. Verify the command returned normally with printf '%s\n' "$?" immediately afterwards.

Tip

A successful sample is evidence about that instant, not a diagnosis of a long-running workload.

3. Narrow the view to named containers

Pass one or more names or IDs separated by spaces. This helps when a busy host makes the all-container view hard to scan:

$ docker container stats --no-stream example-web example-worker
CONTAINER ID   NAME             CPU %   MEM USAGE / LIMIT   MEM %   NET I/O       BLOCK I/O   PIDS
abc123def456   example-web      0.02%   18.4MiB / 2GiB      0.90%   12.1kB / 0B   0B / 0B     6
def456abc123   example-worker   0.01%   22.7MiB / 2GiB      1.11%   8.2kB / 0B    0B / 0B     8

A stopped container can be named, but it does not return live statistics. If a name is misspelled, Docker reports that it cannot find the container. Use docker ps -a --format '{{.ID}} {{.Names}} {{.Status}}' to check both running and stopped names without changing state.

4. Include stopped containers when needed

Add --all when the inventory must include stopped containers:

$ docker container stats --all --no-stream
CONTAINER ID   NAME           CPU %   MEM USAGE / LIMIT   MEM %   NET I/O       BLOCK I/O   PIDS
abc123def456   example-web    0.02%   18.4MiB / 2GiB      0.90%   12.1kB / 0B   0B / 0B     6
fedcba654321   old-worker     0.00%   0B / 0B             0.00%   0B / 0B       0B / 0B     0

This option changes the set of containers considered. It does not start the stopped ones. Stopped rows normally contain no live workload, so use them for inventory, not as recent performance measurements.

5. Choose a small, scriptable format

The default table suits people. A narrow template is easier to read in a terminal or log. Use the documented placeholders and quote the template so the shell does not interpret its braces:

$ docker container stats --no-stream \
    --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}' \
    example-web
NAME          CPU %   MEM USAGE / LIMIT   PIDS
example-web   0.02%   18.4MiB / 2GiB      6

Without the table prefix, Docker emits only the fields requested and no header:

$ docker container stats --no-stream --format '{{.Name}} {{.CPUPerc}} {{.MemPerc}}' example-web
example-web 0.02% 0.90%

For one JSON object per container, use the special json format:

$ docker container stats --no-stream --format json example-web
{"BlockIO":"0B / 0B","CPUPerc":"0.02%","Container":"abc123def456","ID":"abc123def456","MemPerc":"0.90%","MemUsage":"18.4MiB / 2GiB","Name":"example-web","NetIO":"12.1kB / 0B","PIDs":"6"}

Warning

The values are formatted strings, not numeric JSON fields. A script that needs arithmetic should parse them deliberately and account for units and the trailing percent sign. For machine integrations that need raw counters or a different sampling model, use the Docker API rather than assuming the display strings are a stable schema.

6. Avoid the common traps

  • --no-stream limits output to the first result. It does not mean "refresh once every second". Leaving it out creates a process that stays attached to the terminal until interrupted. In a service or scheduled job, use it so a forgotten foreground stream cannot hold the job open.
  • --no-trunc keeps full container IDs. It does not increase measurement accuracy and does not alter the container. Use it when a short ID is not enough to identify a container unambiguously.
  • A high CPU percentage is not a host-wide shortage. It is a container usage measurement, and the effect depends on the host, limits and competing workloads.
  • A low memory percentage can still hide a problem. The application may be approaching its container limit, or the limit may be unexpectedly large.
  • Some placeholders are Linux-only. The MemPerc and PIDS placeholders are not available on Windows. For a cross-platform check, select fields the target daemon supports and test the exact output on that platform.

Done means

  • Sampled once. docker container stats --no-stream returned one verified sample without changing container state.
  • Views distinguished. You can tell the default running-only view from --all, which also lists stopped containers.
  • Targeted. You can pick containers by name or ID and stop a live stream with Ctrl-C.
  • Template sound. Your chosen template uses quoted, documented placeholders and treats values as formatted strings.
  • Scripts safe. A scheduled or scripted check uses --no-stream and does not assume that one sample proves a trend.