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.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 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/Ois received and transmitted network data.BLOCK I/Ois data read from and written to block devices.PIDScounts 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-streamlimits 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-trunckeeps 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
MemPercandPIDSplaceholders 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-streamreturned 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-streamand does not assume that one sample proves a trend.