How to Limit Docker Memory and CPU Usage

December 6, 2023

Introduction

By default, Docker containers have unlimited access to the host's physical memory and CPU. Unless carefully controlled, a misbehaving container can consume more resources than planned and cause performance bottlenecks.

In this tutorial, learn how to limit Docker's memory and CPU usage.

How to limit Docker memory and CPU usage.

Prerequisites

Understanding Docker Memory Limits

Limiting container access to memory resources ensures more predictable system performance. Furthermore, memory limits improve security by preventing resource-based attacks.

The following sections clarify the distinction between hard and soft memory limits and provide more information about the potential risks of running out of system memory.

Hard Memory Limits vs. Soft Memory Limits

Docker allows users to define two types of memory limits:

  • Hard limits. When a container exceeds a hard memory limit, Docker takes aggressive actions such as terminating the container. Hard limits are usually applied for critical workloads that cannot afford occasional system instability.
  • Soft limits. When a soft limit is reached, Docker warns the user but does not take immediate action. This type of limit allows occasional resource demand spikes, and administrators use them to set up monitoring and alert systems.

Note: Docker may terminate a container exceeding a soft memory limit if the system runs low on memory.

Risks of Running Out of Memory

Allowing a Docker container to utilize all system memory resources can compromise the system's stability. A misbehaving container may exhaust all the available memory and crash, creating an OOM (out-of-memory) event.

OOM events have the following consequences:

  • Disruption of critical processes.
  • Sub-standard application performance.
  • Problems with co-located containers.

How to Limit Docker Memory Usage

There are several memory-related limitations you can set for a Docker container, including:

  • Configuring the maximum amount of memory a container can use.
  • Defining the amount of memory a container can swap to a disk.
  • Setting the soft limit for the amount of memory assigned to a container.

The table below contains the Docker CLI options for limiting the container's access to memory:

OptionDescription
--memory=, -mSets a hard limit to the maximum physical memory a container can utilize (with a minimum of 6 MB).
--memory-swap=Allocates swap memory available to a container. Since its value represents the total available memory (RAM + swap), --memory-swap must be larger than --memory.
--memory-swappiness=Sets the percentage of anonymous page swaps a container performs.
--memory-reservation=Specifies a soft memory limit. If a hard limit is set for the same container, the soft limit must be smaller than the hard limit.
--kernel-memory=Sets a hard limit to the maximum kernel memory for a container (with a minimum of 6 MB).
--oom-kill-disableDisables killing the container processes when an OOM error occurs.

Learn how to perform common Docker memory limitation operations by referring to the sections below.

Note: If you are learning Docker commands, use this Docker Commands Cheat Sheet as a handy reference.

Set Maximum Memory Access 

Add the --memory option to the docker run command to limit the maximum amount of memory available to a container:

sudo docker run -dit --memory="[memory-limit]" [docker-image]

The value of memory-limit should be a positive integer followed by the suffix b, k, m, or (short for bytes, kilobytes, megabytes, or gigabytes).

For example, to run an Nginx container and set its memory limit to 512 MB, the command is:

docker run -dit --memory="512m" nginx

The -d option starts the container in detached mode.

Running a docker container with a hard memory limit.

Set Swap to Disk Memory Limit

Swap allows Docker to store data by writing directly to the disk after exhausting all RAM assigned to the container. Although this can be a helpful feature, it can also affect system performance.

Before you can run a container with swap limit support, enter the following command to check whether the system supports this option:

sudo docker info

If you receive "WARNING: No swap limit support" in the output, you must change the grub configuration file.

Docker info command showing "No swap limit support" warning.

Follow the steps below to make the necessary changes and enable swapping for a container:

Note: If the docker info command shows no warning, skip to Step 4.

1. Open the file in a text editor of your choice (this article uses nano):

sudo nano /etc/default/grub

2. Add the following line:

GRUB_CMDLINE_LINUX="cdgroup_enable=memory swapaccount=1"
Add memory swap account to grub configuration file.

Save the changes and exit the file.

3. Update the grub configuration with the command below:

sudo update-grub
Updating grub configuration.

Reboot the system to apply the changes.

4. The syntax for running a container with limited physical memory and additional swap memory is:

docker run -dit --memory="[ram]" --memory-swap="[ram+swap]" [image]

For example, to run an Nginx container with a 512 MB RAM limit and 512 MB of swap memory, type:

docker run -dit --memory="512m" --memory-swap="1g" nginx

Note: When setting the swap limit, remember that the value includes the total amount of RAM and swap memory. If you do not want to use swap memory for a specific container, assign--memory and --memory-swap the same values.

Set Soft Limit to Container Memory

The --memory option sets a hard limit that cannot be surpassed. To enforce a soft limit, use the --memory-reservation option. A soft limit option warns when the container uses all assigned memory but does not stop the container's services.

If both the --memory and --memory-reservation options are enabled, the soft limit must be lower than the hard limit.

For example, type the following command to create an Nginx container with a memory reservation of 512 MB and a hard memory limit of 1 GB:

docker run -dit --memory="1g" --memory-reservation="512m" nginx

Docker creates a detached container and prints its ID in the output.

Verify Docker Memory Usage

On a surface level, a container with a memory limit looks like any other Docker container. Use the commands below to verify that the limitations are enforced.

  • Confirm Docker enforces the hard memory limit by checking the container statistics:
docker stats

The limit is displayed in the MEM USAGE / LIMIT column.

The output of the docker stats command showing the hard memory limit.
  • Check swap memory allocation with the docker inspect command:
docker inspect [container-name] | grep MemorySwap
The output of docker inspect showing the MemorySwap value.
  • Confirm the soft memory limit by looking for the MemoryReservation field in the output of the docker inspect command.
docker inspect [container-name] | grep MemoryReservation
The output of docker inspect showing the MemoryReservation value.

How to Limit Docker Container CPU Usage

Docker containers do not have default limitations for using the host's CPU. However, there are several Docker CLI options to define how much CPU resources to assign to a running container. Refer to the table below for more details.

OptionDescription
--cpus=Specifies a limit to the number of CPUs a container can use. The value can be a decimal number (e.g., 1.5).
--cpu-period=Sets the CFS scheduler period. The default value is 100,000 microseconds. This option always goes in pair with --cpu-quota.
--cpu-quota=Defines a CFS quota for a container, i.e., the time before the container is throttled, per CFS scheduler period. For example, setting --cpu-period to 100,000 and --cpu-quota to 150,000 is the same as setting the --cpus option to 1.5.
--cpuset-cpus=Specifies the exact CPU units a container can use. The option takes the numeric value (a comma-separated list or a hyphen-separated range), where the first CPU is number 0, the second is number 1, etc.
--cpu-shares=Allocates CPU cycles to a container. The default value is 1024. A smaller number allocates fewer shares, while a larger number allows more shares. This option sets a soft limit, i.e., the shares are enforced only when CPU cycles are constrained.

Refer to the sections below for examples of Docker's most common CPU-limiting operations.

Limit Number of CPU Cores

The --cpus option provides a way to limit how many CPU cores a container can use. The example below shows the command for running an Nginx container with access to one CPU core:

docker run -dit --cpus="1.0" nginx

The --cpus option's value is a decimal number, i.e., the option also accepts a fraction of a CPU core.

Limit CPU Cycles

When the system has sufficient CPU power, each container can use as much of it as needed. However, when CPU resources are low, use the --cpu-shares option to control the share of CPU cycles available to a container. By default, this value is set to 1024.

For example, to run a container with 2048 CPU shares, run:

docker run -dit --cpu-shares="2048" nginx

When there is resource contention, the container awarded with 2048 CPU shares receives twice as much CPU time as the default container.

Verify Docker CPU Usage

To check CPU limitations for a container, use the docker inspect commands below. For easier search, pipe the output to the grep command.

Below are some examples:

  • View the number of CPUs a container can use:
docker inspect [container-name] | grep NanoCpus

The number in the output represents the number of nano CPUs (one billion nano CPUs corresponds to one CPU).

The output of docker inspect showing the NanoCpus value.
  • View the CPU shares given to a container:
docker inspect [container-name] | grep CpuShares
The output of docker inspect showing the CpuShares value.

Conclusion

This article showed you how to run Docker containers without worrying about creating resource bottlenecks. After reading the instructions, you should know how to limit your containers' memory and CPU usage and optimize your system.

Next, check out How To Use Docker Run Command With Examples for more Docker configuration options.

Was this article helpful?
YesNo
Marko Aleksic
Marko Aleksić is a Technical Writer at phoenixNAP. His innate curiosity regarding all things IT, combined with over a decade long background in writing, teaching and working in IT-related fields, led him to technical writing, where he has an opportunity to employ his skills and make technology less daunting to everyone.
Next you should read
How to Commit Changes to a Docker Image with Examples
February 14, 2024

Docker allows users to run a container based on an existing image. This feature is both time efficient and...
Read more
Docker ADD vs COPY: What are the Differences?
January 25, 2024

If you are creating a Dockerfile, you may be puzzled by how to copy files and directories into it...
Read more
Docker Image Size - How to Keep It Small?
April 10, 2024

Docker images can easily become too large to handle, which is why it is important to keep their size under...
Read more
How to Override Entrypoint Using Docker Run
September 18, 2024

Entrypoint is a Docker instruction used to set up the default executable when the container is run. You can...
Read more