Docker · Resource Management

Docker CPU Shares Explained: Understanding CPU Limits, Fairness, and Resource Control

Two different ways Docker controls how much CPU time a container gets on a shared host — one sets a hard ceiling, the other sets a relative priority. Knowing which one to reach for is essential once you're running multiple containers in production.

The problem: one container can affect an entire server

Docker makes it easy to run multiple applications — or multiple instances of the same application — on a single physical server. A typical production server might host four containers on four CPU cores, each using a modest, predictable slice of CPU.

But what happens when one container suddenly needs much more CPU? A traffic spike, a large batch job, a background task processing unexpected data, or a bug causing a process to spin — any of these can turn a well-behaved container into a resource hog.

One physical server — 4 CPU cores
Core 1
Core 2
Core 3
Core 4
Container 1
Container 2
Container 3
Container 4

Four containers run on top of four shared cores. How much of each core a container can use depends on its CPU configuration.

Without any CPU management, Docker does not automatically prevent one container from using most of the server's CPU:

Normal usage
Container 1
20%
Container 2
15%
Container 3
10%
Container 4
25%
After a CPU spike
Container 1
390%
Container 2
5%
Container 3
3%
Container 4
2%

On a four-core server, 390% CPU means one container is consuming almost all available CPU. The others are still running, but they slow down as they compete for what's left — leading to slow response times, increased latency, failed health checks, unstable services, and difficulty even accessing the server.

How can we control CPU usage between Docker containers running on the same server?

Docker provides two main mechanisms, and they solve different problems: --cpus (CPU limits) and --cpu-shares (CPU shares).

CPU limits: setting a maximum CPU amount

A CPU limit defines the maximum CPU a container is allowed to consume. For example, docker run --cpus=1 means the container can use at most one CPU core — even if the other three cores on the server are completely unused.

Think of CPU limits like a speed limit on a highway. If the limit is 60 mph, you can't drive faster even if the highway is empty.

Why CPU limits are useful

CPU limits are mainly used for protection. If a bug causes one container to enter a CPU-intensive loop, an unlimited container would spike to 390% and starve everything else. With --cpus=2 set on that container, it's capped at roughly two cores — the problem stays isolated, and the remaining capacity is available for other containers, the OS, monitoring tools, and administrative access.

The limitation of CPU limits

CPU limits provide protection, but they can also waste performance. If every container on a 4-core server is capped at --cpus=1, and only one of them is busy while the other three sit idle, the busy container still can't exceed its 1-core cap — even though three full cores are going unused. For bursty workloads, that's not ideal. This is where CPU shares come in.

CPU shares: sharing CPU fairly

CPU shares work differently. Instead of defining a maximum amount of CPU, shares define how CPU should be divided when multiple containers need it at the same time.

A common misconception: setting --cpu-shares=1024 does not mean a container is capped at some percentage of CPU. CPU shares are not a limit. They don't reserve CPU, and they don't prevent a container from using all available CPU — they only influence distribution during contention.

CPU LIMITS --cpus=1
Container 1
CAPPED
Container 2
idle
Container 3
idle
Container 4
idle
3 idle cores go unused — Container 1 cannot exceed its 1-core cap, no matter what.
Maximum CPU is fixed even when resources are available.
  • Hard maximum — a container can never cross it
  • Protects the host against runaway CPU usage
  • May leave idle CPU capacity unused
CPU SHARES cpu-shares=1024
Container 1
BUSY
Container 2
fair share
Container 3
fair share
Container 4
fair share
Equal shares (1024 each) — Container 1 expands into idle capacity while others keep their fair minimum.
CPU is shared based on priority during contention.
  • Relative priority, not a hard cap
  • Better overall resource utilization
  • Only matters once containers compete for CPU

Scenario walkthrough: four instances, equal shares

Imagine two servers with four CPU cores each, running eight instances total, every one configured with --cpu-shares=1024. Because every instance has the same share value, Docker treats them equally — but the outcome still depends entirely on who else is competing.

Scenario 1 — only Instance 1 is busy
Instance 1
3–4 cores
Instance 2–4
idle
Scenario 2 — two instances busy
Instance 1
≈2 cores
Instance 2
≈2 cores
Scenario 3 — all four instances busy
Instance 1
≈1 core
Instance 2
≈1 core
Instance 3
≈1 core
Instance 4
≈1 core

A container with CPU shares can still consume the entire server when nothing else is competing — shares only kick in once there's contention.

Increasing priority with CPU shares

Shares can also express relative priority. If Instance 1 is set to cpu-shares=2048 while Instances 2–4 stay at 1024, Instance 1 has twice the share value. When all four compete, Instance 1 receives roughly twice the CPU of each of the others — but if the others are idle, Instance 1 can still use whatever's available. Shares influence fairness, not maximum usage.

How Docker CPU shares work internally

Docker relies on the Linux CPU scheduler, which continuously checks which containers need CPU, how much CPU time each has already received, and what their configured weights are. It then distributes CPU time in very small intervals. Over time, usage follows the configured share ratios — but it's not a fixed allocation; it adapts dynamically to the actual workload.

CPU shares vs. CPU limits

The easiest way to remember the difference is by the question each one answers:

Question
Solution
How much CPU can this container ever use?
CPU Limit
Who gets CPU when multiple containers need it?
CPU Shares
How do I protect my server?
CPU Limit
How do I avoid wasting CPU during bursts?
CPU Shares
How do I prioritize one workload?
CPU Shares

At a glance

CPU LIMITS
CPU SHARES
Hard maximum
Relative priority
Protects against runaway CPU usage
Better resource utilization
May leave CPU unused
Only matters when containers compete

Can we use both together?

Yes — many production systems do. A common pattern combines CPU shares of 1024 across all instances for fair sharing during normal operation, with a CPU limit of 2 cores per instance as a ceiling. That gives fair CPU sharing day-to-day, and protection against any single container going rogue.

Final takeaways

CPU limits (--cpus) create a hard ceiling.
CPU shares (--cpu-shares) control fairness, not a maximum.
CPU shares do not stop a container from using all available CPU when nothing else competes.
CPU shares only matter once multiple containers compete for CPU at the same time.
CPU limits protect the server from runaway containers; CPU shares improve performance for bursty workloads.
The right choice depends on whether your priority is protection or maximum resource utilization — production systems often use both together.

Have a similar infrastructure or resource-management problem you're working through?

Get in touch