Resource limits prevent containers from consuming excessive CPU, memory, or I/O, ensuring fair resource allocation and system stability. Without limits, a single runaway container can starve other containers and even crash the host. This guide covers all Docker resource constraint options.
Memory Limits
# Hard memory limit (container is killed if exceeded — OOMKilled)
docker run -d --memory 512m --name web nginx
# Memory with swap
docker run -d --memory 512m --memory-swap 1g nginx
# 512m RAM + 512m swap = 1g total
# Memory reservation (soft limit — guaranteed minimum)
docker run -d --memory 1g --memory-reservation 512m nginx
# Disable OOM killer (not recommended for production)
docker run -d --memory 512m --oom-kill-disable nginx
CPU Limits
# Limit to specific number of CPUs
docker run -d --cpus 2.5 nginx # Use at most 2.5 CPU cores
# CPU shares (relative weight, default 1024)
docker run -d --cpu-shares 512 low-priority-app # Half of default weight
docker run -d --cpu-shares 2048 high-priority-app # Double weight
# Pin to specific CPU cores
docker run -d --cpuset-cpus "0,1" nginx # Only use CPU 0 and 1
docker run -d --cpuset-cpus "0-3" nginx # Use CPUs 0 through 3
# CPU period and quota (fine-grained control)
docker run -d --cpu-period 100000 --cpu-quota 50000 nginx
# 50000/100000 = 50% of one CPU
I/O Limits
# Block I/O weight (relative, 10-1000)
docker run -d --blkio-weight 300 low-io-app
docker run -d --blkio-weight 900 high-io-app
# Device read/write rate limits
docker run -d --device-read-bps /dev/sda:10mb nginx # Max 10MB/s read
docker run -d --device-write-bps /dev/sda:5mb nginx # Max 5MB/s write
docker run -d --device-read-iops /dev/sda:1000 nginx # Max 1000 IOPS read
docker run -d --device-write-iops /dev/sda:500 nginx # Max 500 IOPS write
Process Limits
# Limit number of processes (prevents fork bombs)
docker run -d --pids-limit 100 nginx
# Limit file descriptors via ulimit
docker run -d --ulimit nofile=1024:2048 nginx # Soft:Hard
docker run -d --ulimit nproc=256 nginx
Docker Compose Resource Limits
services:
web:
image: nginx
deploy:
resources:
limits:
cpus: "2.0"
memory: 512M
pids: 100
reservations:
cpus: "0.5"
memory: 256M
db:
image: postgres:16
deploy:
resources:
limits:
cpus: "4.0"
memory: 2G
reservations:
cpus: "1.0"
memory: 1G
Monitoring Resource Usage
# Real-time stats
docker stats
# Stats for specific containers
docker stats web db api
# Output:
# CONTAINER CPU% MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
# web 0.02% 12.5MiB / 512MiB 2.44% 5kB / 2kB 0B / 0B
# db 1.50% 256MiB / 2GiB 12.5% 10kB / 5kB 50MB / 20MB
# JSON output for scripting
docker stats --no-stream --format "{{json .}}" web
Handling OOM Kills
# Check if a container was OOM killed
docker inspect web | jq '.[0].State.OOMKilled'
# Check system logs
dmesg | grep -i "out of memory"
journalctl -k | grep -i oom
# Prevent OOM kills:
# 1. Set appropriate memory limits
# 2. Add memory-swap for overflow
# 3. Monitor container memory usage
# 4. Profile your application memory requirements
Best Practices
- Always set memory limits — containers without limits can crash the host
- Set CPU limits to prevent noisy neighbor problems
- Use
--pids-limitto prevent fork bomb attacks - Monitor resource usage with
docker statsbefore setting limits - Set reservations (minimum guaranteed resources) for critical services
- Leave 10-20% of host resources unallocated for system processes
- Use OOM events as alerts to review and adjust limits