How to Decrease Your Gradle Build Time by Up to 65%

DevOps Best PracticesDevOps ProcessDevOps Tools

YOUR COSMETIC CARE STARTS HERE

Find the Best Cosmetic Hospitals

Trusted • Curated • Easy

Looking for the right place for a cosmetic procedure? Explore top cosmetic hospitals in one place and choose with confidence.

“Small steps lead to big changes — today is a perfect day to begin.”

Explore Cosmetic Hospitals Compare hospitals, services & options quickly.

✓ Shortlist providers • ✓ Review options • ✓ Take the next step with confidence

This article is based on original research and benchmarks published by Keval Patel at kevalpatel2106.wordpress.com. All benchmark figures and commands are drawn from that source.

Why Build Time Matters

Gradle is a powerful and flexible build system. For Android projects it handles compiling Java source to .dex bytecode, merging resources and assets, packaging everything into an .apk, and signing the result. That flexibility comes at a cost: Gradle is noticeably slower than some alternative build systems.

The time lost adds up quickly. If you spend six hours a day on a project and trigger a debug build fifteen times, even a two-and-a-half-minute build time means roughly 35 minutes of idle waiting per day — around 10% of your working hours. Cutting that in half returns meaningful productive time every week.

The benchmarks below were measured against the open-source Google I/O Android application, which contains more than 28 dependencies and 41,538 method references — a realistic, non-trivial project. The test machine was a 13-inch MacBook Pro (2016). Your results will vary depending on hardware, project size, and current Gradle version.

Gradle build summary showing unoptimised build time

Baseline: Build Without Any Optimisations

Before making any changes, measure where you stand. The --profile flag tells Gradle to record the time taken by every task and write an HTML report to /projectDir/build/reports/profile/.

./gradlew android:assembleDebug --profile

On the test machine, this produced a baseline of 2 minutes 43 seconds for a full debug build. That is the number to beat.

Gradle profile report showing baseline build time of 2 min 43 sec

Understanding the Gradle Build Lifecycle

Every Gradle build passes through three distinct phases:

  1. Initialisation — Gradle determines which projects are part of the build.
  2. Configuration — Gradle evaluates every build.gradle script, applies plugins, and constructs the task dependency graph.
  3. Execution — Gradle runs the tasks identified during configuration to actually build the project.

Only the execution phase does real work. The first two phases are overhead that runs on every invocation. To isolate and measure that overhead, use the --dry-run flag, which forces Gradle to initialise and configure without executing any tasks:

./gradlew android:assembleDebug --dry-run --profile

On the Google I/O project, initialisation and configuration alone consumed approximately 7.8 seconds — time that could be recovered with the right settings.

Optimisation 1: Configure on Demand

The Google I/O project contains two modules: android (the app) and server (backend code). When you build the Android module, Gradle still configures the server module by default — wasting roughly a second for something you do not need.

The --configure-on-demand flag tells Gradle to configure only the projects actually required for the requested tasks. Test it like this:

./gradlew android:assembleDebug --dry-run --profile --configure-on-demand

To make this permanent, add the following to your gradle.properties file:

org.gradle.configureondemand=trueCode language: JavaScript (javascript)

You can also enable it in Android Studio under Preferences > Build, Execution, Deployment > Compiler and checking Configure on demand.

Android Studio compiler preferences showing Configure on Demand checkbox

Benchmark result: ~1 second saved during configuration (~6% improvement on init/config overhead).

Optimisation 2: Enable the Gradle Daemon

The Gradle Daemon keeps a Gradle JVM process alive in the background between builds. Instead of starting a fresh JVM for every build invocation, subsequent builds reuse the warm process — eliminating JVM startup time and benefiting from JIT-compiled hot paths.

The first build after enabling the daemon will not show a speedup because the daemon itself needs to start. Every subsequent build on the same machine will be significantly faster.

./gradlew android:assembleDebug --dry-run --profile --configure-on-demand --daemon
Gradle profile report showing reduced init and configuration time with daemon enabled

To enable the daemon permanently, add to gradle.properties:

org.gradle.daemon=trueCode language: JavaScript (javascript)

Note: The Gradle daemon is enabled by default from Gradle 3.0 onwards. If you are already on a modern version you may not need this setting explicitly.

Benchmark result: ~4.5 seconds saved on init/config (~71% improvement on that phase).

Optimisation 3: Keep Gradle Up to Date

Each Gradle release brings performance improvements. From Gradle 2.4 onwards, Gradle caches build artifacts so that unchanged tasks are skipped on subsequent builds. Newer releases also improve incremental compilation and up-to-date checks.

Check your current wrapper version in gradle/wrapper/gradle-wrapper.properties and update the distributionUrl to the latest stable release. You can find the current release on the official Gradle website.

gradle-wrapper.properties file showing distributionUrl set to Gradle 3.3

After updating the wrapper and re-running with daemon and configure-on-demand, the combined init/config overhead dropped further.

Gradle profile showing further reduced configuration time after upgrading Gradle version

Benchmark result: ~0.7 seconds additional saving on init/config, for a combined ~82% reduction in that phase.

Optimisation 4: Increase the JVM Heap Size (Dex In Process)

From Android Studio 2.0 onwards (requiring build tools 23.0.2 or higher), the Android Gradle plugin supports dex in process. Previously, each dx (dexing) step spawned a separate JVM process. With dex in process, all dx work runs inside the same JVM as the Gradle daemon, eliminating the overhead of spawning and communicating with child processes.

Diagram showing multiple separate dx processes before dex-in-process
Diagram showing unified dex-in-process architecture sharing a single JVM with Gradle daemon

Because dex and Gradle now share a single JVM, that JVM needs more heap space. The default daemon heap is approximately 1 GB, which is often too small. Add the following to gradle.properties to increase it:

org.gradle.jvmargs=-Xmx3072m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

The right value depends on your machine’s available RAM and project size. The original author found 3 GB effective for the Google I/O project; increasing beyond that showed diminishing returns on their hardware. Tune this value for your own environment.

Running a full clean debug build with these settings combined:

./gradlew android:assembleDebug --profile --configure-on-demand --daemon
Gradle profile showing full build time reduced to approximately 1 minute

Benchmark result: Full build dropped from 2 min 43 sec to approximately 1 min — a 63% reduction.

Optimisation 5: Modularise and Parallelise Your Build

If your project has multiple independent modules, Gradle can build them in parallel rather than sequentially. Enable this with:

org.gradle.parallel=trueCode language: JavaScript (javascript)

The more independent modules your project has, the greater the benefit. For single-module projects or tightly coupled modules, the gain will be minimal. The Google I/O benchmark showed a marginal additional improvement at this stage (cumulative total ~64.5% reduction), because the project does not have many independent subprojects.

To maximise the benefit from parallel builds, deliberately structure your codebase into independent feature or library modules that have no circular dependencies on one another.

Gradle profile showing build time with parallel builds enabled

Other Small but Useful Practices

Avoid Heavy Computations in Build Scripts

Configuration-phase code in build.gradle runs on every build. Expensive operations — such as executing a shell command to count Git commits for a version code, or downloading a file from a remote URL — add latency to every single build invocation. Move such operations out of the configuration phase or cache their results.

Avoid Dynamic Dependency Versions

Using a trailing + in a dependency version string forces Gradle to contact the remote repository on every build to check for a newer version:

# Avoid this — triggers a network round-trip on every build
compile 'com.android.support:appcompat-v7:23.0.+'Code language: PHP (php)

Pin to an exact version instead, and update dependencies deliberately:

# Prefer this — resolved from cache
compile 'com.android.support:appcompat-v7:23.0.2'Code language: PHP (php)

TL;DR — The Complete gradle.properties Configuration

Add the following lines to your project’s gradle.properties file to apply all of the above optimisations at once:

# Keep the Gradle JVM alive between builds
org.gradle.daemon=true

# Only configure projects needed for the requested tasks
org.gradle.configureondemand=true

# Build independent modules in parallel
org.gradle.parallel=true

# Increase heap to support dex-in-process
# Adjust -Xmx to suit your machine's available RAM
org.gradle.jvmargs=-Xmx3072m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8Code language: PHP (php)

These settings, combined with keeping your Gradle wrapper version current and pinning dependency versions, produced a roughly 65% reduction in debug build time on the Google I/O project in the original benchmarks.

Summary of Benchmark Results

Optimisation appliedMeasured saving
Configure on demand~1 s (6% of init/config time)
+ Gradle Daemon~4.5 s (71% of init/config time)
+ Updated Gradle version~0.7 s additional (82% cumulative)
+ Increased heap / dex in process (full build)1 min 43 s saved (63% of total build)
+ Parallel builds~64.5% cumulative total build reduction

All figures are from benchmarks run on a 13-inch MacBook Pro (2016) against the Google I/O open-source Android project. Results on your hardware and project will differ.

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x