Home / Alt manpages / docker-stats(1)

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

Read Docker Container Load Without Losing the Signal

A container that suddenly eats memory rarely announces itself, which is exactly why docker stats exists as your first live check. You will watch live resource usage, narrow the view to one container, and capture a single sample for a script or incident note. Allow about ten minutes if the container name is already known.

This command reads statistics from the Docker daemon. It does not change a container, but access to the daemon is privileged on many installations, so run it as your normal account first. If Docker reports a socket permission error, use the access method approved for your host rather than adding yourself to a group as a quick fix. The examples match Docker CLI 29.8.1 from the installed docker-ce-cli package, version 5:29.8.1-1~ubuntu.24.04~noble.

1. Check the installed command

Confirm which binary and client version will run:

$ command -v docker
/usr/bin/docker
$ docker version --format '{{.Client.Version}}'
29.8.1

The manpage describes docker stats as an alias for docker container stats. The installed help lists four useful controls: --all, --format, --no-stream and --no-trunc.

Checkpoint

If the version command fails, fix the Docker CLI or daemon connection before you try to interpret an empty stats view.

2. Watch running containers

Start the normal live view:

$ docker stats
CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O     PIDS
2626d6c28708   parish        0.02%     2.298GiB / 31.13GiB 7.38%     26.5MB / 22.9MB 0B / 0B       14
f002e1ad8f1e   cache         0.02%     19.35MiB / 2GiB     0.94%     5.27MB / 7.72MB 0B / 0B       10

The real output refreshes continuously. Press Ctrl-C to stop watching; this only stops the client display. By default only running containers appear. A line carries the container ID and name, CPU percentage, memory used and limit, memory percentage, network received and sent, block-device read and write, and the number of processes or kernel threads the container created.

Do not read a single high CPU value as a diagnosis. Stats are a moving observation, and the workload, host contention and sampling moment all matter. A rapidly rising memory value or PIDS count is a useful prompt for a closer look, not a verdict on its own.

3. Focus on named containers

Pass one or more container names or IDs after the options:

$ docker stats parish cache
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %   NET I/O       BLOCK I/O   PIDS
2626d6c28708   parish    0.02%     2.298GiB / 31.13GiB 7.38%   26.5MB / 22.9MB 0B / 0B     14
f002e1ad8f1e   cache     0.02%     19.35MiB / 2GiB     0.94%   5.27MB / 7.72MB 0B / 0B     10

Replace those names with containers that exist on your host. An ID prefix also identifies a container. A stopped container can be selected but gives no live data; if a name looks wrong, check it with docker ps -a, which is also read-only and includes stopped containers.

4. Capture one reproducible sample

Use --no-stream when a command must finish instead of refreshing forever:

$ docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}' parish
NAME      CPU %     MEM USAGE / LIMIT    PIDS
parish    0.02%     2.298GiB / 31.13GiB  14

The table prefix keeps a header; without it, the template prints only the fields you request. The fields used here are documented by Docker: .Name, .CPUPerc, .MemUsage and .PIDs. This is ordinary read-only monitoring and needs no privilege beyond daemon access itself.

Checkpoint

Run the command again and compare the two samples. If it exits cleanly with the header present, you have a finite command suitable for a shell loop, a log capture or a manual incident record.

5. Produce machine-friendly JSON

Docker's format option can emit one JSON object per selected container:

$ docker stats parish --no-stream --format '{{json .}}'
{"BlockIO":"0B / 0B","CPUPerc":"0.02%","Container":"2626d6c28708","ID":"2626d6c28708","MemPerc":"7.38%","MemUsage":"2.298GiB / 31.13GiB","Name":"parish","NetIO":"26.5MB / 22.9MB","PIDs":"14"}

Do not assume every numeric-looking value is JSON number data. The output shown by Docker contains quoted strings such as CPUPerc and PIDs, including the percent sign and display units. Parse the JSON before extracting fields, and treat units as part of the value unless your own conversion is explicit.

6. Include stopped containers only when it helps

Add --all when you need the complete container list:

$ docker stats --all --no-stream
CONTAINER ID   NAME        CPU %   MEM USAGE / LIMIT   MEM %   NET I/O     BLOCK I/O   PIDS
2626d6c28708   parish      0.02%   2.298GiB / 31.13GiB 7.38%   26.5MB / 22.9MB 0B / 0B     14
e1a2b3c4d5e6   old-worker  0.00%   0B / 0B             0.00%   0B / 0B     0B / 0B       0

Stopped entries normally show no useful live activity. Combining --all with --no-stream is a useful quick inventory, but it can add noise when you are investigating a running service; prefer an explicit container name for a narrow question.

7. Avoid the common interpretation traps

  • Memory is not the whole host view. On Linux, the Docker CLI subtracts cache usage from the total when reporting container memory, so a CLI value is not necessarily what you would see from the stats API.
  • PIDS counts threads as well as processes. A surprisingly large value can mean thread creation, even when a normal process listing looks small.
  • Output can be truncated. Add --no-trunc if IDs or names must stay unshortened; do not use it reflexively in a wide terminal or a log expecting fixed line lengths.
  • No data is not the same as no container. A stopped container has no live sample. Verify its state with docker ps -a before changing a deployment.

Done means

  • Live view works. You can run docker stats and stop its display with Ctrl-C.
  • Selection works. You can select a container by name or ID and read the main columns.
  • Sampling works. You can use --no-stream for one sample and --format for stable, limited output.
  • Stopped containers are understood. You know --all includes them, and that they give no live statistics.
  • Nothing changed. You have not changed or restarted any container.