Docker
CPU Allocation
Containerization
Resource Management
Virtualization

How many CPUs does a docker container use?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A Docker container does not come with a fixed CPU count unless you explicitly configure one. By default, its processes can compete for time on the host’s available CPUs, and the amount of CPU they actually consume depends on both the scheduler and the application’s own parallelism. The right mental model is access and limits, not a built-in number of cores.

Default Behavior Means “Use the Host Scheduler”

If you start a container without CPU-related flags, Docker does not reserve a dedicated set of CPUs for it. The container’s processes are ordinary processes from the kernel’s point of view, placed inside cgroups and namespaces.

That means:

  • a single-threaded program may only use about one core worth of time
  • a multi-threaded program may spread across several cores
  • nothing stops a busy container from competing across many host CPUs unless you impose limits

A simple example:

bash
docker run --rm python:3.12 python -c "sum(i * i for i in range(10**7))"

This container is not assigned “two CPUs” or “four CPUs.” It simply runs wherever the host scheduler allows.

Limit Total CPU With --cpus

If you want a hard upper bound, the simplest flag is --cpus.

bash
docker run --rm --cpus 1.5 python:3.12 python -c "while True: pass"

This means the container may consume up to one and a half CPUs worth of time. Under the hood, Docker usually translates that into a CPU quota and period.

You can express the same configuration more explicitly:

bash
1docker run --rm \
2  --cpu-period 100000 \
3  --cpu-quota 150000 \
4  python:3.12 python -c "while True: pass"

That gives the container 150000 microseconds of CPU time per 100000-microsecond period, which is effectively 1.5 CPUs.

Restrict Which Cores Are Available

Sometimes the question is not “how much CPU time,” but “which CPUs may run this workload.” For that, use --cpuset-cpus.

bash
docker run --rm --cpuset-cpus 0,1 ubuntu:24.04 bash -lc 'nproc && grep Cpus_allowed_list /proc/self/status'

This restricts the container to CPU 0 and CPU 1. It does not guarantee that the application will use both. It only limits where the scheduler may place the work.

This distinction matters for benchmarking, NUMA-sensitive workloads, or noisy-neighbor control.

Shares Are Not Hard Limits

Docker also supports --cpu-shares, but that is a relative weight, not a hard ceiling.

bash
docker run -d --name app-a --cpu-shares 2048 nginx
docker run -d --name app-b --cpu-shares 1024 nginx

If the host is under CPU contention, app-a gets roughly twice the CPU time of app-b. If the host is idle, both may use more CPU than the share numbers might suggest. So shares answer a fairness question, not a strict allocation question.

Measure What the Container Is Actually Doing

Use docker stats for live usage.

bash
docker stats

CPU percentages can exceed 100% on multi-core hosts because Docker often reports one full core as 100%. So 250% usually means about two and a half cores worth of usage, not an error.

To inspect configured limits rather than live usage, use docker inspect.

bash
docker inspect my-container --format '{{.HostConfig.NanoCpus}}'
docker inspect my-container --format '{{.HostConfig.CpusetCpus}}'

Those values tell you what Docker allowed, not what the process is consuming at every instant.

Common Pitfalls

  • Assuming a container automatically gets a fixed CPU count when no CPU flags are set.
  • Confusing --cpu-shares with a strict maximum.
  • Thinking --cpuset-cpus 0,1 guarantees the application will fully use both cores.
  • Reading docker stats percentages without remembering that numbers above 100% are normal on multi-core hosts.
  • Setting aggressive CPU limits and then blaming Docker for throughput that the limit itself prevented.

Summary

  • By default, a Docker container does not have a fixed CPU count.
  • It can compete for time across host CPUs unless you apply limits.
  • Use --cpus for a hard overall limit and --cpuset-cpus to restrict which cores are available.
  • Use --cpu-shares only when you want relative weighting under contention.
  • Distinguish between configured access, actual runtime usage, and the application’s own ability to run in parallel.

Course illustration
Course illustration

All Rights Reserved.