What Is the Runtime Performance Cost of a Docker Container

What is the runtime performance cost of a Docker container?

An excellent 2014 IBM research paper “An Updated Performance Comparison of Virtual Machines and Linux Containers” by Felter et al. provides a comparison between bare metal, KVM, and Docker containers. The general result is: Docker is nearly identical to native performance and faster than KVM in every category.

The exception to this is Docker’s NAT — if you use port mapping (e.g., docker run -p 8080:8080), then you can expect a minor hit in latency, as shown below. However, you can now use the host network stack (e.g., docker run --net=host) when launching a Docker container, which will perform identically to the Native column (as shown in the Redis latency results lower down).

Docker NAT overhead

They also ran latency tests on a few specific services, such as Redis. You can see that above 20 client threads, highest latency overhead goes Docker NAT, then KVM, then a rough tie between Docker host/native.

Docker Redis Latency Overhead

Just because it’s a really useful paper, here are some other figures. Please download it for full access.

Taking a look at Disk I/O:

Docker vs. KVM vs. Native I/O Performance

Now looking at CPU overhead:

Docker CPU Overhead

Now some examples of memory (read the paper for details, memory can be extra tricky):

Docker Memory Comparison

Is there a formula for calculating the overhead of a Docker container?

It's not a formula per se, but you can gather information about resource usage in the container by examining Linux control groups in /sys/fs/cgroup.


See this excellent post by Jérôme Petazzoni of Docker, Inc on the subject.

See also Google's cAdvisor tool to view container resource usage.

This IBM research paper documents that Docker performance is higher than KVM in every measurement.

Container Fails to Start: Insufficient memory for the Java Runtime Environment to continue

I see that your Docker image uses Ubuntu 22.04 LTS as its base. Recently base Java images were rebuilt on top of this LTS version, which caused a lot of issues on older Docker runtimes. Most likely this is what you're experiencing. It has nothing to do with memory, but rather with Docker incompatibility with a newer Linux version used as a base image.

Your operational server has Docker server version 20.10.10, while the failing server has version 20.10.09. The incompatibility issue was fixed exactly in Docker 20.10.10. Some more technical details on the incompatibility issue are available here.

The solution would be to upgrade the failing server to at least Docker 20.10.10.

How to find how a container was started: docker run or docker-compose up?

For investigation purposes I created the most simplest docker-compose.yml:

version: "2.4"
image: "hello-world"

Then run it with docker-compose up

And lastly the normal way: docker run -it --name cli hello-world

So I had two stopped containers:

$ docker ps -a
6a8d53ff45a4 hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago cli
d54f7a2ae8b2 hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago compose_hello_1

Then I compared inspect output of both:

diff <(docker inspect cli) <(docker inspect compose_hello_1)

I found out that there are labels which compose creates:

             "Labels": {}
"Labels": {
"com.docker.compose.config-hash": "251ebf43e00417fde81d3c53b9f3d8cd877e1beec00ebbffbc4a06c4db9c7b00",
"com.docker.compose.container-number": "1",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "compose",
"com.docker.compose.service": "hello",
"com.docker.compose.version": "1.24.1"

Also compose uses another network:

             "NetworkMode": "default",
"NetworkMode": "compose_default",

You should do it on your environment and try to find out differences where you can surely differentiate between both launch ways.

Related Topics

Leave a reply