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.

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.

Understanding the Gradle Build Lifecycle
Every Gradle build passes through three distinct phases:
- Initialisation — Gradle determines which projects are part of the build.
- Configuration — Gradle evaluates every
build.gradlescript, applies plugins, and constructs the task dependency graph. - 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.

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

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.

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

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.


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

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.

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 applied | Measured 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.