Optimizes Gradle build performance through caching strategies, configuration cache, parallel execution, and memory tuning to achieve 50-80% faster builds for large projects...
Dramatically improve Gradle build speed through intelligent caching, parallel execution, and configuration optimization. Properly configured projects can see 50-80% reduction in build times.
Use this skill when you need to:
Add these lines to gradle.properties:
# Enable caching (87% faster with cache hits)
org.gradle.caching=true
org.gradle.configuration-cache=true
# Enable parallel execution
org.gradle.parallel=true
# Configure memory (4GB for most projects)
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# Keep daemon running (enabled by default)
org.gradle.daemon=true
Then run:
./gradlew build --build-cache --parallel
The build cache stores task outputs and reuses them when inputs haven't changed.
Enable local cache in gradle.properties:
org.gradle.caching=true
Results: 87% faster builds on cache hits (35s down to 4.5s example)
Configure remote cache for CI (optional but recommended for teams):
// settings.gradle.kts
buildCache {
local {
isEnabled = true
}
remote<HttpBuildCache> {
url = uri("https://build-cache.company.com/cache/")
isEnabled = true
isPush = System.getenv("CI") == "true" // Only CI pushes
credentials {
username = System.getenv("CACHE_USERNAME")
password = System.getenv("CACHE_PASSWORD")
}
}
}
Configuration cache skips the entire configuration phase when inputs haven't changed. Gradle 8.11+ gives 65% median time reduction.
Enable in gradle.properties:
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn # Start with warnings
Verify compatibility:
./gradlew help --configuration-cache
Check configuration cache report:
build/reports/configuration-cache/<hash>/configuration-cache-report.html
Execute tasks from different projects simultaneously.
Enable in gradle.properties:
org.gradle.parallel=true
org.gradle.workers.max=4 # Adjust based on CPU cores (default: num cores)
Effectiveness: 30-50% faster for multi-module projects
Note: Requires independent subprojects; tasks within same project run sequentially unless using configuration cache.
Proper JVM heap allocation is critical for large projects.
For most projects (up to 30 modules) in gradle.properties:
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
For large projects (30+ modules):
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=2g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Memory allocation guidelines:
-Xmx2g to -Xmx4g)-Xmx4g to -Xmx6g)-Xmx6g to -Xmx8g)Gradle daemon is enabled by default but can be optimized.
In gradle.properties:
org.gradle.daemon=true
org.gradle.daemon.idletimeout=3600000 # 1 hour (default: 3 hours)
Manage daemon:
./gradlew --status # Show running daemons
./gradlew --stop # Stop all daemons
./gradlew build --no-daemon # Run without daemon (for debugging)
Lock dependency versions for reproducible, faster builds.
Generate lock files:
./gradlew dependencies --write-locks
Result: gradle.lockfile and configuration-specific lock files created
Verify against locks:
./gradlew dependencies --verify-locks
Visualize build performance and identify bottlenecks.
One-time scan:
./gradlew build --scan
Automatic scanning in builds:
// build.gradle.kts
plugins {
id("com.gradle.build-scan") version "3.17"
}
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
publishAlways()
}
Detect CI environment and adjust behavior:
// build.gradle.kts
val isCi = System.getenv("CI") != null
if (isCi) {
// CI-specific build scan
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
publishAlways()
tag("CI")
tag(System.getenv("CI_COMMIT_REF_NAME") ?: "unknown")
}
}
# Gradle Optimization Configuration
# === CACHING ===
# Build cache - stores task outputs for reuse (87% faster on hits)
org.gradle.caching=true
# Configuration cache - skip configuration phase (65% faster median time)
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn
# === EXECUTION ===
# Parallel execution - run tasks from different projects simultaneously
org.gradle.parallel=true
org.gradle.workers.max=4
# Daemon - long-running JVM process (enabled by default)
org.gradle.daemon=true
org.gradle.daemon.idletimeout=3600000
# === MEMORY ===
# JVM heap for Gradle daemon (adjust for project size)
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# === DEBUGGING ===
# Uncomment if needed
# org.gradle.logging.level=info
# org.gradle.debug=true
Start with warnings to identify incompatible plugins:
# gradle.properties
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn # Shows warnings instead of failing
Monitor output:
./gradlew build 2>&1 | grep -i "configuration-cache"
Fix issues, then switch to strict mode:
# Once all issues are fixed
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=fail # Now strict
# .github/workflows/build.yml
name: Optimized Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Setup Gradle (official action with caching)
uses: gradle/actions/setup-gradle@v4
with:
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
- name: Build with Gradle (optimized)
run: ./gradlew build --parallel --build-cache --configuration-cache --scan
env:
CI: true
- name: Upload build scans
if: always()
uses: actions/upload-artifact@v4
with:
name: build-scans
path: build/reports/
# .gitlab-ci.yml
image: gradle:8.11-jdk21-alpine
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.caching=true -Dorg.gradle.parallel=true"
GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle"
cache:
key: "$CI_COMMIT_REF_SLUG"
paths:
- .gradle/wrapper
- .gradle/caches
build:
stage: build
script:
- chmod +x ./gradlew
- ./gradlew assemble --parallel --build-cache --configuration-cache
artifacts:
paths:
- build/libs/*.jar
expire_in: 1 day
test:
stage: test
script:
- ./gradlew test --parallel --build-cache --configuration-cache
artifacts:
when: always
reports:
junit: build/test-results/test/TEST-*.xml
# Before optimization
time ./gradlew clean build
# Real 2m 30s
# After optimization
time ./gradlew build --parallel --build-cache --configuration-cache
# Real 0m 45s (82% improvement!)
# Generate build scan for detailed analysis
./gradlew build --scan
# Opens scan at https://scans.gradle.com
# Generate lock files
./gradlew dependencies --write-locks
# Verify locks in CI
./gradlew dependencies --verify-locks
# Update lock files (controlled)
./gradlew dependencies --write-locks --refresh-dependencies
See references/commands-and-troubleshooting.md for complete command reference, troubleshooting guide, and optimization checklist.