Docker CPU Limit Converter

Convert between the CPU flags and see what each one actually enforces. Two of them are not limits at all, and one of them throttles work that averages well below its ceiling.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Convert. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A fractional CPU limit

Exactly a quota and a period, and the window is what causes throttling

--cpus=1.5

Shares on their own

A weight rather than a limit, so nothing caps this container at all

--cpu-shares=512

A pinned cpuset

Caps usage only as a side effect, and fails to start on a smaller host

--cpuset-cpus=0-3

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Using --cpu-shares as a limit

    It is a relative weight that only applies under contention. On an idle host the container uses everything, so the limit you thought you set does not exist.

    Instead:Use --cpus for a ceiling. Keep shares for expressing priority between containers that genuinely compete.

  2. Raising the CPU limit to fix latency spikes

    If the cause is quota throttling on a bursty workload, more quota helps only until the burst grows. The stall is caused by the window, not by the total.

    Instead:Check nr_throttled in cpu.stat first. A shorter --cpu-period reduces the size of each stall.

  3. Leaving thread pools at their defaults in a limited container

    Most runtimes read the host's core count, so a one-CPU container starts as many workers as the host has cores and they all contend for one core's quota.

    Instead:Set GOMAXPROCS, UV_THREADPOOL_SIZE and equivalent limits explicitly from the container's CPU limit.

--cpus is sugar for a quota, and a quota is a window

--cpus=1.5 sets --cpu-quota=150000 with --cpu-period=100000: 150ms of CPU in every 100ms window. That is enforced per window, not on average.

Throttling that does not show up as high CPU

Once a container has spent its quota for the current 100ms period it is stopped until the next one starts. A process idle for 80ms then wanting four cores for 20ms is throttled hard, while its average usage sits comfortably under the limit. The symptom is latency spikes with flat CPU graphs, and the evidence is nr_throttled in the cgroup's cpu.stat.

--cpu-shares does nothing on an idle host

It is a proportional weight, applied only when containers compete for the same core. A container with 2 shares on a quiet machine uses everything available. So it constrains nothing you can test and behaves completely differently the moment a neighbour gets busy.

--cpuset-cpus pins rather than limits

It ties the container to named cores, so it caps usage only as a side effect of how many you named. It is also not portable: a cpuset naming core 8 fails to start on a four-core host, which is how an image that works on one machine does not on another.

Setting a quota without a period is a factor-of-ten mistake

The period defaults to 100000 microseconds. Somebody who sets --cpu-quota=50000 thinking in milliseconds gets half a CPU rather than the fifty they had in mind, or the other way round. Using --cpus avoids the arithmetic entirely.

Runtimes still size their thread pools from the host

A quota does not change what /proc/cpuinfo reports. Modern JVMs read the cgroup; Node's libuv pool, Go before 1.25, and most thread-pool defaults do not. A container limited to one CPU on a 64-core host starts 64 workers that then fight over one core's quota.

The Kubernetes equivalents

limits.cpu is the quota; requests.cpu is the share weight. So a Kubernetes pod with a request and no limit is the --cpu-shares situation, with all the same testing problems.

More docker tools

Docker Container Image Reference Parser Is that a registry or a Docker Hub user? Dockerfile Linter What this image will do to you later docker run to Kubernetes YAML And the flags that have no equivalent Docker Compose to Kubernetes And why depends_on has no equivalent Docker Logging Driver Generator json-file never rotates Dockerfile Non-Root USER Generator Numeric, or Kubernetes rejects it Docker OCI Image Labels Generator One of them actually does something Docker Hub Pull Rate Limit Calculator Counted per IP, not per person Docker Registry Storage Calculator Deleting a tag frees nothing Docker Build Context Analyzer All of it uploads before anything runs Docker Compose to docker run Converter Names stop resolving Docker Compose Version Migrator version: is obsolete now Docker Compose Network and Port Viewer Everything reaches everything Docker Command Explainer Which flags hand over the host Docker BuildKit Cache Mount Generator apt deletes the cache you just mounted Docker BuildKit Secret Mount Generator ARG is in docker history forever Docker .dockerignore Pattern Tester *.log does not match logs/app.log Docker Image Manifest Viewer unknown/unknown is not broken Docker Image Config Viewer Anyone who can pull can read your Env Docker Registry Token Decoder Check the scope before the credentials Docker HEALTHCHECK Generator Docker does nothing when it fails Docker Network Subnet Calculator 31 networks, then it stops Docker History Analyzer The rm did not save anything Docker Run to Compose Converter Some flags have no equivalent Docker CMD and ENTRYPOINT Tester Why docker stop takes ten seconds Docker Port Mapping Tester -p reaches past your firewall Docker -v to --mount Converter -v invents missing directories Docker Restart Policy Simulator The backoff resets after ten seconds Docker Exit Code Explainer 137 is two different problems Docker Memory Limit Calculator -m 512m allows a gigabyte Docker Compose Interpolation Tester An unset variable is an empty string Docker Environment Variable Precedence Tester Your shell does not reach the container Docker Compose Override Merge Previewer An override can add a port, never remove one Dockerfile Multi-Stage Build Analyzer Which stages reach the image Dockerignore Validator It is not .gitignore

Elsewhere on the site