Understand your build structure and performance
TL;DR: Today I learned that you can trace your build performance with bloop, and it’s especially easy when using Metals. The setup might not be obvious for some.
When working with multi-module projects, build times can sometimes increase unexpectedly. There are a few ways to analyze that statically, but you can always see the live data from your bloop compilation. Let’s explore those options.
Static analysis
When your build.sbt
file grows complex it’s easy to lose track of which depends on which. This not only creates confusion and complicates onboarding, but also to slower builds and frustration in consequence.
If you are looking to simply better understand your build then sbt-project-graph provides an excellent visualization tool.
To use it simply:
- Add
addSbtPlugin("com.dwijnand" % "sbt-project-graph" % "0.4.0")
to yourproject/plugins.sbt
- Open
sbt
console - Run
projectsGraphPng
- Open
target/projects-graph.png
When executed in https://github.com/typelevel/weaver-test source code, this creates following image:
While this effectively illustrates the project topology, it doesn’t help seeing the critical path in the build times.
Live data
Luckily for us, the bloop build server provides tracing that we can use. The details are described in the docs, so instead let’s see how to get started quickly!
Considering you’re using Metals with VSCode, here’re the steps:
- Run local Zipkin instance with
docker run -d -p 9411:9411 openzipkin/zipkin
- In VSCode open settings (via
CTRL+,
/⌘+,
) and filter forbloop
- Add item
-Dbloop.tracing.enabled=true
as on the picture below - When prompted, allow Metals to reboot bloop server
That’s it! tracing is running. Now go ahead and compile the project, do some changes if you will.
Once your project is compiled, open your browser and navigate to http://localhost:9411/zipkin/ - this is the Zipkin instance we started with docker. Press “Run Query” and you should see a list of spans. I suggest sorting by duration in descending order, the longest span should represent the entire project build (if this is what you’re interested in).
Now press SHOW to the right and you should see the details of this span, including child spans (representing roughly compilation units).
This is a great complimentary tool to the project graphs shown above. You can map specific parts of the graph you saw above to the time each component takes to build. Notice how the graph also shows you which parts of the build were executed in parallel, and how frameworkjvm
needed to wait for corejvm
to finish.
Performance data outside Metals/VSCode
The performance feature is native to bloop, so you can enable it with other editors, as well as just when just compiling from scripts/console. You can enable it easily by exporting env variable export BLOOP_JAVA_OPTS="-Dbloop.tracing.enabled=true"
and restarting bloop.