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:

  1. Add addSbtPlugin("com.dwijnand" % "sbt-project-graph" % "0.4.0") to your project/plugins.sbt
  2. Open sbt console
  3. Run projectsGraphPng
  4. Open target/projects-graph.png

When executed in https://github.com/typelevel/weaver-test source code, this creates following image:

image of weaver project dependencies

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:

  1. Run local Zipkin instance with docker run -d -p 9411:9411 openzipkin/zipkin
  2. In VSCode open settings (via CTRL+, / ⌘+,) and filter for bloop
  3. Add item -Dbloop.tracing.enabled=true as on the picture below image of bloop jvm properties settigns
  4. 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).

zipkin list of spans

Now press SHOW to the right and you should see the details of this span, including child spans (representing roughly compilation units).

zipkin span details

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.