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.
docker-ce-cli.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.
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.
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:
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.
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.
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.
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.
--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.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.docker container stats --no-stream returned one verified sample without changing container state.--all, which also lists stopped containers.Ctrl-C.--no-stream and does not assume that one sample proves a trend.