Why You Should be using Parallel Builds

Gradle's parallel task execution builds independent sub-projects simultaneously, cutting one real-world commit-to-deploy time in half. This post explains the --parallel and --max-workers flags introduced in Gradle 2.4, walks through how Gradle determines build order from the dependency graph, and warns about the circular-dependency and memory-resource pitfalls that can erase your gains.

Coveros Staff

November 15, 2015

No one likes their software build to take forever.  If you are not using binary dependency between your multiple projects as projects grow in size the more time to build and test is going to be needed.  Luckily Gradle has a feature to help with this dilemma. By building multi-project projects using parallel task execution the amount of time for your build process can be significantly reduced.  After implementing a parallel execution build on a recent project significant time savings were realized.  The time from code commit to deploy was cut in half!

Say for example you have Project A, Project B, Project C, and Project D.  Project D depends on project B and project A depends on all other projects (this is probably the project that contains your web application).  Gradle will handle the orchestration of determining when each build should be built during the build task. In serial execution the project order might look something like this:

  1. Project B
  2. Project C
  3. Project D
  4. Project A

Using parallel execution might look something like:

  1. Project B and Project C build simultaneously
  2. Project D
  3. Project A

Using multiple threads Gradle is going to execute the buid task for Project B and Project C simultaneously, followed by Project D, then Project A.  What happens when I run ‘Gradle build’ on the root project?  A lot. Gradle is going to compile the source code, compile test code, execute unit and maybe integration tests, and assuming all of that is successful, package the artifact.

So you’re sold and decide you need to implement this time saving tip.  What do you need to do to make this work?  Simple…. Mostly. Starting in Gradle 2.4 you need to add the –parallel option and should also add the –max-workers option. –parallel tells Gradle to run in parallel execution. –max-workers tells Gradle how many tasks can be executed at the same time. The default is the number of processors which is why I say you should add, but it required.

While implementing these changes there are things you definitely need to be mindful of while you’re building. The first is to identify any circular dependencies between projects.  If they exist, eliminate them!  Second, make sure you are building on a server with enough resources.  The more workers you use the more cores and more memory that is needed.  Assuming you are running this as part of your CI pipeline, continuously monitor resources on the server.  The last think you want is out of memory errors during the build.  If you can’t increase server resources, decrease the number of workers, it’s going to take some experimenting to determine the right configuration for your environment.

Implementing parallel execution in your CI Pipeline is going to provider faster feedback to you or your team.  This enables your team to push more often and potentially reduce the time it takes for features to move to production — helping to deliver business value.

Coveros Staff

Coveros Staff

This post represents the collective insights of the Coveros team. Our staff consists of software experts who bring deep experience in secure agile development, DevOps, testing, and software quality. Over the past 20 years, Coveros has trained more than 30,000 professionals and worked with half of the Fortune 100 companies on mission-critical software development challenges. We draw on this extensive experience to share practical insights, proven strategies, and real-world solutions that help organizations build better software faster and more securely.