How do you limit a container's CPU and memory usage?

6 minintermediateresource-limitscgroupsmemory-limitscpu-limits

Quick Answer

--memory sets a hard memory limit, beyond which the container's process is killed by the kernel's OOM killer — the same underlying mechanism covered in the Kubernetes stack. --cpus sets a fractional CPU limit (e.g., --cpus=1.5 for one and a half cores' worth of CPU time), enforced via the Linux kernel's CFS quota mechanism. The container is throttled, not killed, if it tries to exceed this. Both flags translate directly into the same cgroup configuration Kubernetes and other orchestrators use under the hood.

Detailed Answer

Setting a memory limit

docker run --memory="512m" myapp

This directly configures a cgroup memory limit. If the container's processes try to use more than 512MB total, the kernel's OOM killer terminates the offending process. Kubernetes uses this same underlying mechanism, with the same tradeoffs, for its own memory limits and OOMKilled behavior. Memory can't be gracefully throttled the way CPU can — there's no way to make an over-budget memory allocation just run more slowly. So exceeding this limit always means termination, not degradation.

docker run --memory="512m" --memory-swap="1g" myapp

--memory-swap sets the combined memory-plus-swap limit. If you don't set it, it defaults to double the --memory value, allowing some swap usage as a buffer. Setting --memory-swap equal to --memory disables swap for the container entirely.

Setting a CPU limit

docker run --cpus="1.5" myapp

--cpus caps the container at that many CPU cores' worth of processing time. Fractional values are allowed — 1.5 means one and a half cores. The kernel enforces this with the Completely Fair Scheduler (CFS). Unlike memory, exceeding a CPU limit doesn't kill the container — the kernel simply throttles it. The container gets less CPU time than it's trying to use, so it keeps running, just more slowly.

docker run --cpu-shares=512 myapp

--cpu-shares is an older mechanism. Instead of an absolute cap, it sets a relative weight for CPU time when the host's CPU is under contention. A container with --cpu-shares=1024 gets twice the CPU time of one with --cpu-shares=512, but only when the host's CPU is actually contended. If the host isn't contended, either container can use up to 100% of available CPU. This is a different model from --cpus's hard cap — the two are sometimes used together: a relative priority under contention, plus an absolute ceiling.

Why exceeding these limits behaves so differently

Memory limits cause termination. CPU limits cause throttling. This comes from the nature of each resource: memory is incompressible, a process either has an allocation or it doesn't, while CPU time is compressible, a process can simply be scheduled less often and run more slowly without crashing. Both mechanisms rely on the same underlying Linux cgroups. Kubernetes's resources.limits are, at the implementation level, just a more structured, orchestrator-managed way of setting these same --memory/--cpus-equivalent cgroup constraints.

Inspecting current resource usage

docker stats
# CONTAINER   CPU %   MEM USAGE / LIMIT   MEM %
# my-api       12.34%   340MiB / 512MiB      66.4%

docker stats gives a live view of actual resource consumption against configured limits. Use it to confirm a configured limit is realistic — one that sits comfortably above typical usage, with headroom. Check this before a real incident forces the question, not after.

Why setting these limits matters, even on a single host

Without explicit limits, a single misbehaving or leaking container can consume all of a host's available CPU or memory, starving every other container sharing that machine. This is the same "noisy neighbor" problem that affects any shared infrastructure, just at the scale of one Docker host instead of a whole cluster. Setting sensible --memory and --cpus limits on every container is basic operational hygiene — true even in a simple single-host Docker Compose setup, not just in orchestrated, multi-node environments.