Optimising Gradle build time in multi-module Android projects

Build time optimization is a continuous process which is extremely important for big teams. In this article, I’ll share some non-standard tricks that could help you to save extra seconds|minutes on your builds.

Spoilers alert! This tricks works on some projects but could not work for yours.

I hope you’ve already read Gradle Guides and Official Android Guides, if not I strongly recommend to do it before reading this article.

Let’s begin

If you’ve ever experienced your system to be irresponsive during the build most probably it’s your SSD/HDD that slows you down. There is only one solution for this problem — do less writes/reads on your drive during compilation.

Problem identified. How to solve it?

Using RamDisk! The idea is to keep all your intermediate build results in memory. Faster IO — faster builds. Yeah, this simple. As a small bonus — your SSD will live much longer.

All you need to do is to execute the following command in the console, for macOS:

Or follow instructions here, for Linux, and here using ImDisk for Windows.

Personally, I need 4GB of space but this amount could be different for your project.

The second step would be — telling Gradle where to put all your build files.

We are good to go.

If, locally, you haven’t noticed any significant improvements on build time there still a chance to improve it on your CI server.

Second trick. Again, it’s related to IO during compilation. We’ll try to reduce the amount of generated files.

One way to do it — is to remove our dependencies, at least from build output, fortunately, Gradle can do it out of the box. All we need to do is replace implementation declaration with compileOnly. But this is not the whole trick, an app will crash once you’ll try to access some of the classes from these dependencies. The way to fix it fortunately also simple. All you need to do is add this dependencies with runtimeOnly declaration in your app module and testImplementation in the same module. If you are using it in tests. You’ll notice that this trick will not work for the app itself since we need to have all dependencies there.

Let’s say we have implementation rxJava dependency in 5 feature modules, in this case, all build outputs of this modules will contain 5 rxJava’s binaries, but once we’ll replace all dependencies to compileOnly rxJava and add runtimeOnly rxJava to our app module suddenly we have reduced our build time a little bit and amount of generated files in our output (1 instead of 5).

Thanks a lot for reading till this point! Do let me know if this hints helped you to improve build time. And leave a comment if you want me to work on data-driven version of this article.

Staff Software Engineer @LyftLevel5 https://github.com/stepango | https://level5.lyft.com/

Staff Software Engineer @LyftLevel5 https://github.com/stepango | https://level5.lyft.com/