E-NO
Docker capacity planning 7 Min Read

Docker Capacity Planning: Practical Examples for Right-Sizing Containers

calendar_today Published: 2026-09-03
update Last Updated: 2026-09-03
analytics SEO Efficiency: 97%
Technical guide illustration for Docker Capacity Planning: Practical Examples for Right-Sizing Containers.

A practical guide to planning Docker host and container capacity, estimating resources, setting limits, recognizing scaling signals, and applying safety margins with concrete examples.

Intro

Docker capacity planning is the process of estimating and allocating compute, memory, storage, and network resources for containerized workloads. Without deliberate planning, teams often hit unexpected outages, wasted cloud spend, or missed performance targets. This guide provides a practical, step-by-step approach to capacity planning for Docker hosts and containers. You will learn how to inventory your environment, set resource limits, verify configurations, diagnose problems, and establish an operational checklist. The examples use Docker CLI commands and Compose files, and all numbers are illustrative, to be adapted to your workload.

Version and Environment Inventory

Before changing any limits, record the current Docker version, host specifications, and running workloads. This baseline helps you understand what you have, identify containers without limits, and track changes over time.

Verify Docker and OS versions

Run:

docker version --format '{{.Server.Version}}'

Example output:

20.10.12

Record the host kernel and OS:

uname -r && cat /etc/os-release | head -n 2

Example output:

5.4.0-109-generic
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"

Inspect host resources

Use free -h for memory, nproc for CPUs, and df -h for storage.

Example host: 4 vCPU, 16 GB RAM, 100 GB disk.

free -h
nproc
df -h /

Typical output:

              total        used        free      shared  buff/cache   available
Mem:           15Gi       3.2Gi        10Gi       256Mi       1.8Gi        11Gi
Swap:         2.0Gi          0B       2.0Gi
4
/dev/sda1        98G   32G   61G  35% /

List running containers and their resource usage

docker stats --no-stream

Example output (truncated):

CONTAINER ID   NAME   CPU %   MEM USAGE / LIMIT     MEM %   NET I/O          BLOCK I/O   PIDS
abc123         web    0.50%   256MiB / 15.6GiB      1.60%   1.2MB / 300kB    0B / 0B     10
def456         db     2.10%   1.1GiB / 15.6GiB      7.03%   500kB / 200kB    10MB / 2MB  25

Note which containers have no memory limit (shown as host total) and which have explicit limits. In the example above, both containers show the host total (15.6GiB) as the limit, meaning no limit is set. This baseline helps identify where to focus planning.

Prerequisites for capacity planning

  • Docker Engine 20.10 or later (for cgroup v2 support).
  • Access to Docker daemon with appropriate permissions.
  • A test or staging environment to validate changes before production.
  • Monitoring tooling (e.g., Prometheus, cAdvisor, or Docker stats) to collect metrics.

Estimating Resource Needs

Before setting limits, estimate what each container actually needs. Use a combination of observation, load testing, and application knowledge.

Observe existing usage

If the container is already running, let it run under normal load for at least 24-48 hours and capture peak usage. Use docker stats periodically or a monitoring system.

Example: For a web container, you might see average CPU 0.3 cores, peak 1.2 cores; memory average 300 MB, peak 800 MB. Use peak as a starting point for limits.

Load testing

If the container is new or you anticipate a traffic spike, simulate load with tools like ab, wrk, or hey. Run the container with generous limits initially, then measure.

docker run -d --name myapp-test --cpus=4 --memory=4g myimage:latest
# Generate load from host or another container
ab -n 10000 -c 100 http://localhost:8080/

While the test runs, monitor docker stats myapp-test and note peak CPU and memory.

Application knowledge

Consult developers or documentation for expected resource profiles. A Java application with a 2 GB heap will need more memory than the heap size due to overhead. A CPU-bound video transcoder may need multiple cores.

Add a safety margin

Limits should not be set at the exact peak. Add a margin of 20-30% for headroom and unexpected spikes. For the web example above, you might set a CPU limit of 1.5 cores and memory limit of 1 GB.

Quick check 1 of 2

What does the 'docker stats' command live stream for containers?

Reference passage 2 states that 'docker stats' provides CPU, memory usage, memory limit, and network I/O metrics.

Safe Configuration Path

Set resource limits on containers to prevent a single workload from starving others. The main controls are CPU and memory limits. Storage and network limits are less commonly managed per container, but you should plan for them at the host level.

CPU limits

Docker uses CPU shares for relative weight and CPU quota for hard limits. For simplicity, start with CPU quota using --cpus.

Example: limit a container to 1.5 CPUs

docker run -d --name myapp --cpus="1.5" myimage:latest

To verify:

docker inspect myapp --format '{{.HostConfig.NanoCpus}}'

Expected output: 1500000000 (nano CPUs).

If the container attempts to use more than 1.5 cores, it will be throttled.

Memory limits

Memory limits are critical because exceeding them can cause the OOM killer to terminate processes. Use --memory and optionally --memory-swap.

Example: limit memory to 512 MB and disallow swap

docker run -d --name myapp --memory="512m" --memory-swap="512m" myimage:latest

By setting --memory-swap equal to --memory, the container cannot use swap.

To verify from inside the container, check cgroup limits:

docker exec myapp cat /sys/fs/cgroup/memory.max

Expected output (in bytes): 536870912.

Docker Compose configuration

For multi-container applications, define limits in docker-compose.yml.

services:
  web:
    image: nginx:1.23
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 256M
        reservations:
          cpus: '0.25'
          memory: 128M

Note: deploy.resources applies to Swarm mode. For non-Swarm Compose, use the mem_limit and cpus keys (version 2 format) or the resources block in version 3 with docker-compose v1.28+.

For the latest Compose specification, use the resources block under services (not deploy) if you are not using Swarm:

services:
  web:
    image: nginx:1.23
    resources:
      limits:
        cpus: '0.50'
        memory: 256M
      reservations:
        cpus: '0.25'
        memory: 128M

Storage and network planning

  • Storage: Monitor host disk usage and container writable layers. Use docker system df to see space used by images, containers, and volumes.
docker system df

Example output:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          12        3         4.2GB     2.1GB (50%)
Containers      8         5         1.5GB     100MB (6%)
Local Volumes   4         2         3.8GB     0B (0%)
Build Cache     0         0         0B        0B
  • Network: If using user-defined bridge networks, ensure adequate IP range and avoid port exhaustion.

Avoid setting storage quotas per container unless using specific storage drivers (e.g., overlay2 with project quotas). For most teams, host-level monitoring suffices.

Verification and Diagnostics

After applying limits, verify they are effective and monitor for signs of resource pressure.

Check effective limits

Use docker inspect to confirm limits are set:

docker inspect --format '{{.HostConfig.Memory}} {{.HostConfig.NanoCpus}}' myapp

Example output: 536870912 1500000000.

Monitor runtime usage

docker stats myapp --no-stream

Observe MEM USAGE / LIMIT column; if usage is close to limit, the container may be under stress.

Simulate load to validate limits

For CPU, run a stress tool inside the container (if available) and observe throttling:

docker exec myapp sh -c "apt-get update && apt-get install -y stress && stress --cpu 4"

In another terminal, docker stats will show CPU % capped at the limit (e.g., 150% for 1.5 CPUs). For memory, you can allocate memory in a test container and confirm it gets killed at the limit.

Host-level diagnostics

  • free -h to see host memory pressure.
  • vmstat 1 to observe CPU run queue and swapping.
  • iostat -x 1 for disk I/O saturation.
  • docker events to catch OOM kills or restarts.

Expected results and thresholds

Define acceptable thresholds. For example:

  • CPU throttling: if nr_throttled in cgroup CPU stats increases significantly, the container is being throttled.
  • Memory: if container memory usage consistently exceeds 80% of limit, consider increasing limit or optimizing application.
  • Host: maintain at least 20% free memory and CPU headroom for the Docker daemon and system processes.

Failure Modes and Recovery

Common capacity-related failures and how to recover.

Out of Memory (OOM) kills

When a container exceeds its memory limit, the kernel OOM killer terminates a process inside the container. The container may restart if a restart policy is set.

Detection: docker inspect myapp --format '{{.State.OOMKilled}}' returns true. Also look for kernel logs (dmesg | grep -i oom).

Recovery: Increase memory limit if the workload legitimately needs more, or optimize the application. Rollback by restoring the previous limit and restarting the container.

CPU starvation

If a container is CPU throttled, it may experience high latency. Check docker stats for high CPU % equal to limit, and inspect cgroup cpu.stat for nr_throttled:

docker exec myapp cat /sys/fs/cgroup/cpu.stat

If throttling is severe, increase CPU quota or move workload to a larger host.

Disk full

Containers writing logs or data can fill the host disk. This can cause Docker daemon issues.

Detection: df -h shows high usage; docker system df shows large volumes or container logs.

Recovery: Clean up unused images/containers (docker system prune), rotate logs, or add storage. To avoid recurrence, configure log rotation in daemon.json or per container.

Rollback plan

Always document the previous resource settings. Use configuration files (Compose, scripts) under version control. To rollback, revert the configuration and restart the container or service. Example:

docker compose down && git checkout previous-compose.yml && docker compose up -d

Quick check 2 of 2

In the sample output of 'docker stats' for redis1 and redis2, what is the memory usage of redis1?

The sample output shows redis1 has 796 KB memory usage.

Operations Checklist

Use this checklist for ongoing capacity management.

ItemFrequencyCommand / Action
Review container resource usageWeeklydocker stats --no-stream
Check host memory and CPU headroomWeeklyfree -h, uptime
Check disk usage (host and Docker)Weeklydf -h, docker system df
Review for OOM killsAfter incidentsdocker inspect <container> --format '{{.State.OOMKilled}}'
Review log sizes and rotationMonthlydu -sh /var/lib/docker/containers//.log
Update resource limits based on trendsAs neededEdit Compose file or run commands, then apply
Test disaster recovery for limitsQuarterlySimulate memory exhaustion in staging

Additional operational practices

  • Set alerts for host resource usage above 80%.
  • Use cAdvisor or Prometheus to collect container metrics.
  • Perform capacity reviews after each major release.
  • Document each service's expected baseline and peak resource usage.

Scaling Signals and Capacity Planning

Knowing when to scale is part of capacity planning. Watch for these signals:

  • Consistent high CPU usage (>80% of limit) over several days.
  • Memory usage approaching limit with frequent OOM kills.
  • Increasing response times or error rates.
  • Host running out of resources (high load average, low free memory).

When scaling, consider both vertical (increase limits) and horizontal (add replicas) approaches. For stateful services like databases, vertical scaling may be easier; for stateless web apps, horizontal scaling with a load balancer is common.

Conclusion

Docker capacity planning is an ongoing discipline, not a one-time task. Start with a clear inventory of your environment, set conservative limits, verify them under simulated load, and monitor for deviations. Use the checklist to review capacity regularly, and always have a rollback plan. By following the practical examples in this guide, you can avoid common resource pitfalls and maintain reliable containerized services.

Next steps:

  • Run the version and environment inventory on one host.
  • Set CPU and memory limits on your most critical container.
  • Verify the limits with docker inspect and docker stats.
  • Simulate a memory or CPU spike to observe behavior.
  • Document your baseline and establish a monitoring routine.

Related Research

Article Quality Score

Reader usefulness 97%
  • check_circle Reader-ready guide
  • check_circle Practical examples included
  • check_circle Clean SEO article URL