Docker Container Sizing Calculator

Calculate optimal Docker container resource allocation. Get memory, CPU recommendations and cost estimates for Kubernetes, ECS, and Docker Swarm.

RPS
ms
x
MB

Quick Reference

CPU Millicores
1000m = 1 CPU Core
100m = 0.1 CPU core
Memory Units
Mi = Mebibytes
1 Gi = 1024 Mi
Request vs Limit
Request = Guaranteed
Limit = Maximum allowed

Recommended Container Resources

Calculated
CPU Request
0m
Per container
Memory Request
0 Mi
Per container
Est. Monthly Cost
$0
All replicas

Resource Allocation Details

Resource Request Limit

Total Cluster Resources

Metric Value

Cost Estimates (Monthly)

Platform Estimated Cost

Configuration Snippet


                        

Key Takeaways

  • Set requests based on P50-P75 of actual resource usage plus 10-20% headroom
  • CPU limits should be 2-3x the request to allow bursting
  • Memory limits should be 1.25-1.5x the request to prevent OOM kills
  • JVM-based apps need 512MB-1GB minimum; Go apps can run on 10-50MB
  • Monitor throttling events and OOM kills to fine-tune allocations

Docker Container Resource Sizing Guide

Workload Type Recommended CPU Recommended RAM Notes
Stateless API (Node.js)0.25–1 vCPU128–512 MBScale horizontally
Java/Spring Boot1–2 vCPU512 MB–2 GBJVM overhead
Python web (Django/Flask)0.5–1 vCPU256 MB–1 GBWorker-dependent
Static file server (nginx)0.1–0.5 vCPU64–256 MBVery lightweight
PostgreSQL (dev/small)0.5–2 vCPU256 MB–4 GBDisk I/O critical
Redis (cache)0.1–0.5 vCPU64 MB–4 GBRAM = data size
ML inference (CPU)2–8 vCPU4–16 GBModel-dependent
Base Image Compressed Size Use Case Notes
scratch~0 MBStatically compiled Go, RustNo shell, minimal attack surface
alpine:3.x~3 MBSmall utility containersmusl libc, limited packages
debian:slim~30 MBGeneral purpose (slim variant)Compatible, smaller than full
ubuntu:22.04~28 MBGeneral purposeFamiliar tools
node:18-alpine~40 MBNode.js appsPreferred for prod
node:18 (full)~350+ MBNode.js (dev)Avoid in production
python:3.11-slim~45 MBPython appsGood balance
openjdk:17-slim~180 MBJava appsConsider eclipse-temurin
Scenario CPU Request CPU Limit Memory Request Memory Limit
Over-provisioned (safe)= limit2× need= limit1.5× need
Burstable (common)50–70% of peakpeak= actual need1.2–1.5× need
Best-effort (avoid in prod)0000
Guaranteed QoS= limit= limit= limit= limit
Rule of thumbStart with p50 loadAllow 2–3× burstActual RSSAdd 20–50% headroom

Proper container sizing is critical for application performance, stability, and cost optimization. Under-provisioned containers lead to performance issues and crashes, while over-provisioned containers waste resources and money. This comprehensive guide covers best practices for sizing Docker containers across different workloads and platforms.

Understanding Container Resources

CPU Resources

Container CPU is typically measured in cores or millicores (1 core = 1000 millicores):

  • CPU Requests: Guaranteed minimum CPU allocation
  • CPU Limits: Maximum CPU the container can use
  • CPU Shares: Relative priority when competing for CPU
  • Throttling: Container is throttled when exceeding limits

Memory Resources

Memory allocation directly impacts container behavior:

  • Memory Requests: Minimum memory guaranteed to the container
  • Memory Limits: Maximum memory before OOM (Out of Memory) kill
  • Swap: Generally disabled in container environments
  • OOM Score: Priority for killing under memory pressure

Sizing by Workload Type

API/Web Servers

Traffic Level CPU Request Memory Request Notes
Low (<100 RPS) 100-250m 128-256 MB Single core sufficient
Medium (100-1000 RPS) 250-500m 256-512 MB Scale horizontally
High (1000+ RPS) 500m-1000m 512 MB-1 GB Multiple replicas needed

Background Workers

Job Type CPU Memory Considerations
I/O Bound 100-250m 256-512 MB More workers, less CPU each
CPU Bound 500m-2000m 256-512 MB Match to job parallelism
Memory Intensive 250-500m 1-4 GB Watch for memory leaks

Database Containers

Database containers require careful sizing for performance:

  • PostgreSQL: 1-2 CPU cores, 2-8 GB RAM base
  • MySQL: 1-2 CPU cores, 1-4 GB RAM base
  • MongoDB: 2-4 CPU cores, 4-16 GB RAM
  • Redis: 1 CPU core, memory sized to dataset

Language/Runtime Considerations

JVM-Based (Java, Kotlin, Scala)

  • JVM requires significant base memory (512MB-1GB minimum)
  • Set -Xmx to 75-80% of container memory limit
  • Consider container-aware JVM flags (-XX:+UseContainerSupport)
  • Startup can be slow; consider longer health check delays

Node.js

  • Single-threaded by default; typically need <1 CPU per process
  • Set --max-old-space-size for heap limit
  • Use cluster module or multiple containers for concurrency
  • Base memory: 128-256 MB for simple apps

Python

  • GIL limits CPU parallelism per process
  • Use multiple workers (gunicorn, uvicorn) for concurrency
  • Memory usage varies significantly by libraries
  • NumPy/Pandas can use significant memory

Go

  • Efficient runtime with low base memory (10-50 MB)
  • Excellent concurrency with goroutines
  • Set GOMAXPROCS if limiting CPU
  • Often can use smaller containers than other languages

.NET Core

  • Modern .NET is container-optimized
  • Base memory 100-200 MB
  • Configure GC for container environments
  • Consider ReadyToRun for faster startup

Pro Tip: Right-Size Based on Data

Don't guess - use actual metrics. Collect at least 2 weeks of usage data, account for peak periods and batch jobs, use P95 CPU and max memory as baseline, and review quarterly.

Requests vs Limits Best Practices

Setting Requests

Base requests on actual observed usage:

  • Use P50-P75 of historical resource usage
  • Include headroom for normal variation (10-20%)
  • Consider startup requirements
  • Monitor and adjust based on actual usage

Setting Limits

Limits should prevent runaway resource consumption:

  • CPU: 2-3x the request (allows bursting)
  • Memory: 1.25-1.5x the request (prevent OOM)
  • Consider P99 usage plus safety margin
  • Never set memory limits lower than peak usage

QoS Classes in Kubernetes

QoS Class Configuration Eviction Priority
Guaranteed Requests = Limits Last to be evicted
Burstable Requests < Limits Middle priority
BestEffort No requests/limits First to be evicted

Monitoring and Optimization

Key Metrics to Track

  • CPU utilization: % of allocated CPU used
  • Memory usage: Working set vs limit
  • Throttle events: CPU throttling frequency
  • OOM events: Out of memory kills
  • Container restarts: Stability indicator

Tools for Profiling

  • docker stats: Real-time container metrics
  • cAdvisor: Container resource analysis
  • Prometheus + Grafana: Historical metrics
  • VPA (Kubernetes): Automatic right-sizing recommendations
  • Goldilocks: VPA recommendations visualization

Common Sizing Mistakes

  • Setting limits too low: Causes OOM kills and restarts
  • No limits at all: One container can starve others
  • Equal requests and limits: Prevents efficient bin packing
  • Ignoring startup requirements: Containers may fail to start
  • Not accounting for sidecars: Service mesh, logging add overhead
  • One-size-fits-all: Different services have different needs

Conclusion

Container sizing is both an art and a science. Start with reasonable defaults based on your workload type and runtime, then iterate based on actual metrics. The goal is to find the sweet spot that ensures reliability and performance while minimizing costs. Regular monitoring and adjustment are key to maintaining optimal sizing as your application evolves.

Frequently Asked Questions

How accurate are the results?
The Docker Container Sizing applies a standard formula to your inputs — accuracy depends on how precisely you measure those inputs. For planning and estimation, results are reliable. For high-stakes or professional decisions, cross-check the output with a domain expert or primary source.
Can I use this on mobile?
Yes — the calculator is designed to work on any device. For complex multi-input calculations on small screens, landscape orientation gives more room to see all fields and results simultaneously.

Frequently Asked Questions

How do I determine the right CPU and memory for a Docker container?
Sizing Docker containers correctly requires measuring actual resource usage, not guessing. Step 1 — Profile the workload: Run your container in a development or staging environment under realistic load. Use: docker stats <container_id> — shows live CPU % and memory usage. docker stats --no-stream — snapshot. Example output: CONTAINER | CPU % | MEM USAGE / LIMIT | MEM % | 4f3a... | 12.5% | 245MiB / 512MiB | 47.8%. Step 2 — Identify p99 resource usage: Look at CPU during peak load (not average — you care about peak). Identify steady-state memory (RSS, not cache). In Kubernetes, query Prometheus: container_cpu_usage_seconds_total and container_memory_working_set_bytes. Step 3 — Set limits and requests: CPU: set request to your p50 (average) load. Set limit to your p99 peak. Memory: set request = expected steady-state RSS. Set limit = steady-state + 20–50% buffer (prevents OOM kills). Example: your API averages 0.2 CPU cores but spikes to 0.8. Memory steady-state: 256 MB, peaks at 350 MB. CPU: request=0.25, limit=1.0. Memory: request=256Mi, limit=450Mi. Step 4 — Iterate: Set conservative limits, monitor, and tune. Use kubectl top pods and HPA (Horizontal Pod Autoscaler) to adapt dynamically. Avoid: setting limits too low (causes throttling/OOM kills). Setting limits too high (wastes cluster resources, reduces scheduling density).
How do I reduce Docker image size?
Smaller Docker images mean faster pulls, less storage cost, reduced attack surface, and faster CI/CD. Strategy 1 — Use multi-stage builds: Build in a large image; copy only the runtime artifact to a minimal final image. Example (Go application): FROM golang:1.21 AS builder. WORKDIR /app. COPY . .. RUN go build -o myapp .. FROM scratch. COPY --from=builder /app/myapp /myapp. CMD ["/myapp"]. Result: build image ~900 MB, final image ~8 MB. Strategy 2 — Choose minimal base images: Use alpine (3 MB) instead of ubuntu (28 MB) when compatible. Use *-slim or *-alpine variants of language runtimes. Strategy 3 — Minimize layers and clean up in the same RUN: Bad: RUN apt-get update. RUN apt-get install -y curl. RUN rm -rf /var/lib/apt/lists/*. (Each RUN creates a layer; cleanup in a different layer doesn't shrink the previous one.) Good: RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*. Strategy 4 — Use .dockerignore: Exclude node_modules, .git, test files, docs, and build artifacts. Example .dockerignore: node_modules/. .git/. *.test.js. coverage/. Strategy 5 — Only COPY what's needed: Don't COPY . . when you only need src/. Copy package.json first to cache dependencies before source changes. Strategy 6 — Avoid installing build tools in the final image: Use builder containers; only copy compiled artifacts. Node.js: install devDependencies in builder stage, copy only production files. Diagnostic tools: docker image history <image> — shows layer sizes. dive (open-source tool): interactive layer explorer. docker images --format "{{.Size}}" — list image sizes.
What is the difference between Docker CPU limits and CPU requests?
CPU limits and requests are Kubernetes concepts (Docker standalone uses --cpus and --cpu-shares). Understanding both is critical for correct sizing. CPU request: The amount of CPU the container is guaranteed. Used by the Kubernetes scheduler to decide which node to place the pod on. If the node has available CPU above the request, the container can burst higher. Example: request=0.5 means the container is guaranteed 0.5 cores. CPU limit: The maximum CPU a container can use. The kernel throttles the container if it exceeds this. Containers CAN be throttled below their limit if the node is contended. Example: limit=2.0 means the container can use up to 2 cores (but may be throttled). Why they're different: Requests affect scheduling (where the pod lands). Limits affect runtime behavior (throttling). Scenarios: Over-provisioned: request = limit = 1.0. Container always gets exactly 1 core. Wastes CPU if workload is bursty. Burstable: request = 0.25, limit = 2.0. Scheduled on nodes with 0.25 CPU free. Can burst to 2 cores when available. OOM (memory only, not CPU): If a container exceeds its memory limit, it's OOM-killed (terminated). CPU throttling is a performance degradation, not a crash. CFS throttling: Kubernetes uses Linux CFS (Completely Fair Scheduler). CPU limits create CFS bandwidth quotas. Even a single-threaded app with an 8-core limit may be throttled due to CFS period mismatches (a known Kubernetes issue). Recommendation: Set memory limits always. Set CPU requests carefully; be conservative with CPU limits or omit them for latency-sensitive workloads.
How do I size containers for a Kubernetes cluster?
Kubernetes container sizing follows a proven approach: measure, set requests, set limits, and iterate. 1. Start with baselines: Use VPA (Vertical Pod Autoscaler) in recommendation mode — it observes actual usage and suggests request/limit values without changing anything. kubectl apply -f https://github.com/kubernetes/autoscaler/blob/master/.../vpa.yaml. Set VPA to Off mode initially: monitor-only. 2. Set requests based on actual p50 load: requests.cpu: your average CPU usage (not peak). requests.memory: your steady-state RSS memory. Scheduler uses these to pack pods efficiently. Under-requesting means pods get scheduled on full nodes → contention. 3. Set limits for protection: limits.cpu: 2–4× CPU request (allow burst). limits.memory: 1.2–1.5× memory request (prevent runaway usage). Memory limit violations = OOM kill. CPU limit violations = throttling. 4. Use Horizontal Pod Autoscaling (HPA): HPA scales pod count based on CPU/memory usage or custom metrics. Better than oversizing individual pods for variable workloads. HPA target: scale at 70–80% CPU utilization. 5. Use Namespace ResourceQuotas: Prevent any one team from consuming all cluster resources. Set default LimitRange for any container without explicit limits. 6. Review and iterate: Use kubectl top pods --containers for live view. Use Prometheus + Grafana for historical trends. Revisit sizing quarterly or after major workload changes. 7. Cost optimization: In cloud (AWS EKS, GCP GKE, Azure AKS): smaller nodes with more of them is often cheaper than fewer large nodes. Consider Spot/Preemptible instances for stateless workloads (save 60–90%).