2

I'm working on a Spring Boot + Kotlin application and want to speedup the bootRun startup and devtools restart time. The restart currently takes around 20-30 seconds which feels painfully slow compared to the near-instant refresh of frontend changes when hot-reloading is possible.

I'm using macOS Big Sur 11.6.7 with the Amazon corretto 17 JDK

mowwwalker
  • 16,634
  • 25
  • 104
  • 157

1 Answers1

1

1. Update local hostname in /etc/hosts on macOS

I found that there was consistently a nearly exactly 5 second delay during the application restart with devtools even on an empty project. I asked about this here: What is happening after Spring Boot Devtools logs "Starting application" and ultimately found that this was due to a hostname resolution issue with the JVM on macOS. The solution as described there is:

  1. hostname -> eg Monroes-MacBook-Pro.local
  2. sudo vim /etc/hosts
  3. add
127.0.0.1 Monroes-MacBook-Pro.local
::1 Monroes-MacBook-Pro.local

2. Use a trigger file for devtools

Initially I had IntelliJ auto rebuild the project which would result in devtools detecting changes to the class files, but this would often result in multiple restarts for one set of changes as mentioned here: DevTools restarts twice in Intellij. Rather than auto rebuilding in IntelliJ and having devtools watch the whole project, I did the following:

  1. Set a trigger file with
# directory with trigger file
spring.devtools.restart.additional-paths=trigger-restart
# trigger file
spring.devtools.restart.trigger-file=trigger
  1. Added a final build step to write to the trigger file

build.gradle.kts

...
task("finalize") {
    doLast {
        println("Writing devtools restart trigger file")
        File("./trigger-restart/trigger").writeText(Instant.now().toString())
    }
}
tasks.compileKotlin {
    finalizedBy("finalize")
}
<EOF>
  1. Added a shortcut for "build module" in IntelliJ After making a set of changes to the application, I use the shortcut to rebuild. At the end of the build, the above "finalize" task is executed, writing to the trigger file, which then results in devtools handling a restart. In my case I chose "capslock + 5" as the "build module" shortcut with the help of Karabiner + Goku

3. Update Gradle props to enable daemon, parallel builds, cache, and max heapsize

gradle.properties

org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=true
systemProp.kotlinVersion=1.6.21
# https://dev.to/martinhaeusler/is-your-kotlin-compiler-slow-here-s-a-potential-fix-4if4
org.gradle.jvmargs=-Xmx8g -Dkotlin.daemon.jvm.options=-Xmx6g

4. Enable gradle configuration caching (experimental / unstable)

Explained in the Gradle docs here gradle.properties

# https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:usage
org.gradle.unsafe.configuration-cache=true

5. Other changes

The changes above had the biggest impact for me, but here are some other pages and recommendations. Pages:

Things to try :

  • Turn on lazy bean initialization with spring.main.lazy-initialization=true. Bean initialization will be delayed until their first use.
  • Use the latest SDK for the JVM version you're using and consider trying another JDK. I ended up using Amazon Corretto 17

Other notes

For reference, the final turnaround time between making changes and having the application running and serving requests again is now 4 - 10 seconds on my computer. The compilation in IntelliJ takes 2-6 seconds and the application restart consistently takes ~2 seconds.

Related links

mowwwalker
  • 16,634
  • 25
  • 104
  • 157