I recently asked myself what the difference would be between running a Spring Boot Application in a Docker Container with a limit on resources like CPU or RAM between running it without limit.
I used my playground application for the tests. Furthermore I decided to go with the spring-boot default plugin to build an image. My hardware: Dell XPS 13 9343 with 8 GiB memory and a core i7-5500U.
This build of the docker container can be executed as follows:
./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=uhlme/springbootplayground
On my machine the build takes between 40s and 3:30min depending on how much is changed in the project and if the used images are already downloaded.
Afterwards the image can be started as follows:
docker run -p 8080:8080 -t uhlme/springbootplayground
By default it uses 4 processors and assigns 2.8 GB of memory to the JVM. The application started in 3.138 seconds. It uses 185MiB and shows a Memory Limit of 8GB (using docker stats).
To limit resources it can be executed as follows (in this example limited to 2GB and 4 Cpus):
docker run -m 2000m --cpus=4 -p 8080:8080 -t uhlme/springbootplayground
|Memory limit||CPU limit||Startup time|
|500MB||4||Fail to start (fixed memory regions require 589919K which is greater than 500M available for allocation)|
I am aware that this is just a very simple benchmark but I think it is enough to prove the point. Also results might differ when using different containers, different hardware or additional tweaking might be possible.
The number of CPUs has a big impact on the startup time of a spring boot application. Even a simple application takes 10s to startup with only one CPU and assigning less than one CPU quickly increases the duration a lot. Thus at least one CPU should assigned.
Using less than 1GB RAM results in a big impact on the startup time. Even a simple application takes 19s instead of 3s. Thus at least 1GB RAM should be assigned