Docker Stats
Docker's built-in runtime resource monitoring command that shows real-time CPU, memory, network I/O, and block I/O usage for running containers. Used for capacity planning and detecting runaway containers before formal monitoring is in place.
Docker Stats — Real-Time Container Resource Monitoring
What Is Docker Stats in Simple Terms?
docker stats is the quickest way to see what resources your containers are consuming right now — CPU usage, memory usage, network traffic, and disk I/O, updated every second in your terminal.
# Live stats for all running containersdocker stats # Output:# CONTAINER CPU % MEM USAGE/LIMIT MEM % NET I/O BLOCK I/O# payment-api 2.5% 128MiB/512MiB 25.0% 2MB/1MB 0B/0B# postgres 0.8% 256MiB/1GiB 25.0% 100B/50B 50MB/5MB# redis 0.1% 12MiB/512MiB 2.3% 500B/200B 1MB/0BReading the Output
CONTAINER <- container name or IDCPU % <- CPU usage as % of total host CPU (200% = 2 full cores on a 4-core host)MEM USAGE <- current memory usedMEM LIMIT <- memory limit set for containerMEM % <- (MEM USAGE / MEM LIMIT) * 100 Warning: > 85% = approaching OOMKillNET I/O <- bytes received / transmitted over networkBLOCK I/O <- bytes read / written to diskPIDs <- number of processes inside containerUseful docker stats Patterns
# One-shot snapshot (no live update) — for scripts and CIdocker stats --no-stream # Stats for specific containers onlydocker stats payment-api postgres # Formatted output for scriptingdocker stats --no-stream \ --format "{{.Name}}: CPU={{.CPUPerc}} MEM={{.MemUsage}} ({{.MemPerc}})"# payment-api: CPU=2.5% MEM=128MiB / 512MiB (25.0%)# postgres: CPU=0.8% MEM=256MiB / 1GiB (25.0%) # Watch for memory pressure — alert if any container above 85%docker stats --no-stream --format \ '{{.Name}} {{.MemPerc}}' | \ awk '{gsub("%","",$2); if($2>85) print "WARNING: " $1 " at " $2 "%"}' # Continuous monitoring with timestampswatch -n 5 'docker stats --no-stream'Updating Limits on Running Containers
# If stats shows a container approaching its memory limit:docker update --memory 1g payment-apidocker update --cpus 2 payment-api# Changes cgroup limits live — no restart needed# Useful for emergency capacity increase during incidentsDocker Stats vs Prometheus
docker stats: Good for: quick checks, development, debugging Bad for: alerting, historical data, multi-host No persistence, terminal-only Prometheus + cAdvisor: Good for: production monitoring, alerting, dashboards Collects same metrics as docker stats but persistently Works across multiple hosts Use for productionTipMemory percentage (
MEM %) is the most important column to watch. When a container reaches 100% of its memory limit, the kernel kills it immediately (OOMKill, exit code 137). Set alerts when any container exceeds 85% — that gives you time to investigate and increase the limit before the OOMKill happens.
Frequently Asked Questions
How current is the data docker stats shows — is it a live measurement or a rolling average?
By default `docker stats` refreshes continuously and shows point-in-time snapshots pulled from the container's cgroup accounting, not a smoothed average, so CPU percentage in particular can look spiky from one refresh to the next for bursty workloads. It reads from the same cgroup interfaces (`/sys/fs/cgroup`) that the kernel itself uses for resource accounting, so the numbers are accurate, just noisy — useful for spotting a runaway container quickly, less useful for capacity planning without averaging over time yourself.
Why shouldn't docker stats be relied on as your only monitoring for production containers?
It only shows what's running right now, on the host you happen to be SSH'd into — there's no history, no alerting, and no aggregation across a fleet, so a container that OOM-killed and restarted five minutes ago leaves no trace in `docker stats` output. It's genuinely useful for live debugging on a single box ('is this container the one eating CPU right now') but needs to be backed by a real metrics pipeline (cAdvisor, Prometheus node/container exporters) for anything beyond ad hoc troubleshooting.