docker stats

Watching Live Resource Usage with docker stats

docker stats is top for containers, refreshed every second, or sampled once with --no-stream. Commit the two changes, start the production stack, send it 3,000 requests through Nginx 75 eight at a time, and sample it:

Committing the limits and sampling the stack under loadShell
git commit -qam "Rotate container logs and fit Node's heap to its memory limit"
P="-p l3-booknest-prod -f compose.yaml -f compose.prod.yaml"
docker compose $P up -d --build --wait >/dev/null 2>&1
docker compose $P exec api node -p 'require("v8").getHeapStatistics().heap_size_limit >> 20'
seq 3000 | xargs -P 8 -I{} curl -s -o /dev/null localhost:33080/api/books &
sleep 3; docker stats --no-stream \
  --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}'
wait
docker exec l3-booknest-prod-api-1 cat /sys/fs/cgroup/memory.peak
Output
195
NAME                     CPU %     MEM USAGE / LIMIT   PIDS
l3-booknest-prod-web-1   12.50%    5.871MiB / 64MiB    5
l3-booknest-prod-api-1   36.55%    37.53MiB / 256MiB   11
l3-booknest-prod-db-1    8.02%     47.97MiB / 512MiB   15
44679168

V8 86,723 's heap limit is now 195 MiB (the 192 MiB old space plus a small young generation), inside the 256 MiB limit; before this commit Nginx reported the whole host, 31.28 GiB, as its limit. CPU % is relative to one CPU (a busy four-core host can show 400%; these ran on a shared 4-CPU machine, so compare ratios). MEM USAGE is the cgroup's memory.current minus inactive page cache. PIDS counts processes and threads.

The cgroup's high-water mark, memory.peak, says 256 MB is generous. docker update --memory changes a running container's limits, but only until docker compose up recreates it, so record decisions in the Compose 514 file. For history rather than snapshots, cAdvisor 19,452 (github.com/google/cadvisor (https://github.com/google/cadvisor 19,452 )) exports the same counters to Prometheus 16,091 ; Prometheus and Grafana graphs them for Kubernetes 5,150 .