Hello, my Gradle builds are slow!

Aurimas
3 min readNov 10, 2021

--

AndroidX team has been working with Gradle to set up an instance of a Gradle Enterprise server and the data we collected through it has led to some interesting findings. I’d like to share one of them.

A screenshot of ge.androidx.dev scans list

Let’s take a look at a build scan from a GitHub action that was building androidx.room. If you quickly squint at task execution time, you see 7m 6s, which seems fairly reasonable given this is only running on 2 cores. However, right next to that number we have the total build time of 49m 54s and that looks highly suspicious 🤔.

High-level build time stats

If you jump over to the Performance tab, we can spot that 42m 47s of the build time is going to Configuration which is a 🚩🚩🚩.

More detailed build time stats

Head over to the Configuration details. Task creation stats look reasonable and plugins are not taking seconds to apply. Task graph calculation and curiously named Other sections seem to add up to our 42m.

We are not able to get much more from this page, so go over to Dependency resolution and here we see that we spent 22m 40s resolving dependencies. This is quite off, but we don’t get any more information, so let’s pop over to Network activity section and here we see a nasty problem — we spent 1h 45s on downloads (luckily it is parallelized).

So much network activity!!!

There are 26 requests that failed and timed out after 1m, this is not great, but still doesn’t account for all of 1h 45s. Scanning through the list we see lots and lots of requests to androidx.dev, our snapshot server. This snapshot server is only meant to serve snapshots of our own libraries, but here we are seeing Gradle attempting to get every dependency we use from it. It is getting 404s for all of them, which our snapshot server hasn’t optimized for. Well here we have it — we really should not be doing this.

So what’s the fix? We need to tell Gradle to not try downloading artifacts that we know are not going to be found on androidx.dev from it. Luckily, Gradle has just an API for this:

repositories {
maven {
url "https://androidx.dev/..."
includeGroupByRegex(“androidx\..*”)
}
}

This tells Gradle that it can only find androidx.* artifacts on this server. Our set up is a tad more complicated, but the PR is very close to the snippet.

How are we looking after? I’m glad you asked, you can see dependency downloading going from 30m+ to around 3m! 🔥

An eagle-eyed observer might have spotted, that it would probably also help to have androidx maven servers be after all the public repositories, however, that reordering is complicated due to how we do project-to-snapshot substitutions in the androidx github set up. It is work-in-progress.

--

--