skip to content

Build Cache and Performance

Why Gradle skips work: up-to-date checks, the local and remote build cache, and the configuration cache, plus parallelism and how to measure a build honestly. It comes up in every conversation about shrinking CI time.

on this pageshow

explore

questions

146 · 5 sections

What does the @Classpath input annotation do, and why would you use it instead of @InputFiles for a collection of jars?

level: juniorimportance: must knowfreq 55%
basics
~10 s

@Classpath marks a task input as a classpath: Gradle hashes the file contents in order but ignores file names and paths. @InputFiles treats each file's absolute path as significant, so it over-invalidates.

open as a page

What are task inputs and outputs in Gradle, and how do you declare them for an ad-hoc task using the runtime API?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Inputs are the files/values a task reads; outputs are what it produces. For ad-hoc tasks you declare them at runtime via task.inputs.file()/dir()/property() and task.outputs.file()/dir() so Gradle can track changes.

open as a page

What does it mean when Gradle marks a task as UP-TO-DATE, and how does Gradle decide that?

level: juniorimportance: must knowfreq 70%
basics
~10 s

UP-TO-DATE means Gradle skipped the task because its inputs and outputs haven't changed since the last run. Gradle compares snapshots of the declared inputs/outputs; if they match, it reuses the previous result.

open as a page

How does @CompileClasspath differ from @Classpath, and how does ABI-based fingerprinting help avoid recompilation?

level: middleimportance: must knowfreq 50%
basics
~10 s

@CompileClasspath fingerprints only the public API (ABI) of jars — class/method/field signatures — ignoring method bodies, private members and resources. So changing only an implementation detail upstream doesn't invalidate downstream compilation.

open as a page

How do you configure runtime classpath normalization to ignore a volatile file like build-info.properties, and why is it needed?

level: middleimportance: must knowfreq 40%
basics
~10 s

In settings.gradle(.kts) use normalization { runtimeClasspath { ignore 'build-info.properties' } }. It strips that file from the runtime-classpath fingerprint so a volatile, build-stamped entry doesn't cause needless cache misses or out-of-date tasks.

open as a page

What does it mean for a Gradle task to be cacheable, and what is the minimum required to make a task's outputs reusable from the build cache?

level: juniorimportance: must knowfreq 70%
basics
~10 s

A cacheable task can store its outputs in the build cache and restore them later instead of re-running. It needs the @CacheableTask annotation and fully declared inputs and outputs.

open as a page

How do you turn the Gradle build cache on, and what is the simplest way to make it the default for everyone on the project?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Set org.gradle.caching=true in the project's gradle.properties so it is on for every build and every developer, or pass --build-cache on a single command to enable it just for that run.

open as a page

When you run a Gradle build, what does the FROM-CACHE outcome next to a task mean, and how does it differ from UP-TO-DATE and executed?

level: juniorimportance: must knowfreq 70%
basics
~10 s

FROM-CACHE means Gradle restored the task's outputs from the build cache instead of running it. UP-TO-DATE means outputs were already on disk and unchanged. Executed means the task actually ran.

open as a page

Where does Gradle's local build cache store its entries by default, and what does it actually hold?

level: juniorimportance: must knowfreq 55%
basics
~10 s

By default the local build cache lives in ~/.gradle/caches/build-cache-1. It stores the outputs of cacheable tasks keyed by a hash, so a later build can reuse them instead of re-running the task.

open as a page

Where in a Gradle project do you configure the push/pull split for the remote build cache, and at what point in the build lifecycle does that configuration take effect?

level: juniorimportance: must knowfreq 45%
basics
~20 s

In settings.gradle(.kts), inside the buildCache { remote<HttpBuildCache> { ... } } block. It takes effect very early — during settings evaluation, before any project is configured — because the cache must be ready before tasks run.

open as a page

How do you turn on Gradle's configuration cache for a build, and what are the two main ways to do it?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Pass --configuration-cache on the command line for a single run, or set org.gradle.configuration-cache=true in gradle.properties to enable it persistently for every build.

open as a page

When you enable the configuration cache and a build reports problems, Gradle prints a link to a configuration-cache-report.html file. What is in that report and how do you use it?

level: juniorimportance: must knowfreq 55%
basics
~20 s

It is an HTML report Gradle generates listing every configuration-cache problem found, grouped by category, with the task or input that caused each one and a stack-trace-like location so you can find and fix the offending code.

open as a page

When the configuration cache is enabled, what does Gradle serialize and store at the end of the configuration phase, and what does that let it skip on the next build?

level: juniorimportance: must knowfreq 60%
basics
~20 s

Gradle serializes the resolved task graph — the tasks to run plus their configured state — to disk. On a cache hit it loads that snapshot and skips the whole configuration phase, going straight to executing tasks.

open as a page

Walk through the difference between configurationCache.requested and configurationCache.active. Give a concrete scenario where requested is true but active is false.

level: middleimportance: must knowfreq 40%
basics
~20 s

requested means the user asked for the configuration cache; active means it is actually operating. They diverge when, for example, the user sets it in gradle.properties but passes --no-configuration-cache on the command line — requested true, active false.

open as a page

What is the BuildFeatures service in Gradle, and how does a plugin obtain it to learn whether the configuration cache is in play?

level: middleimportance: must knowfreq 45%
basics
~10 s

BuildFeatures is a Gradle service exposing whether opt-in features like the configuration cache are requested and active. A plugin gets it via gradle.serviceOf<BuildFeatures>() (or constructor injection) and reads configurationCache.requested / .active.

open as a page

What is the Gradle Daemon and why does reusing a warm daemon make builds faster?

level: juniorimportance: must knowfreq 70%
basics
~10 s

The daemon is a long-lived background JVM that runs your builds. Reusing a warm one skips JVM startup, class loading, and JIT warmup, so subsequent builds start much faster.

open as a page

Why is the second Gradle build in a session usually noticeably faster than the very first one, even when nothing about the project has changed?

level: juniorimportance: must knowfreq 60%
basics
~10 s

Gradle runs in a long-lived background JVM (the daemon). The first build pays JVM startup and HotSpot JIT warmup; later builds reuse that already-warm JVM, so they skip those costs and run faster.

open as a page

What does Gradle's --max-workers flag (or org.gradle.workers.max property) control, and what is its default value?

level: juniorimportance: must knowfreq 55%
basics
~10 s

It caps the maximum number of work items Gradle runs concurrently across the whole build — parallel tasks, test forks, Worker API jobs. It defaults to the number of CPU processors Gradle detects.

open as a page

How do you enable parallel project execution in Gradle, and what exactly does it parallelize?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Pass --parallel on the command line, or set org.gradle.parallel=true in gradle.properties. Gradle then runs tasks from different projects concurrently using the daemon's worker threads, instead of one project at a time.

open as a page

What is Gradle's File System Watching (VFS), and what problem does it solve between consecutive builds?

level: juniorimportance: must knowfreq 55%
basics
~10 s

Gradle keeps an in-memory Virtual File System of file metadata and listens to OS file-change events. Between builds it retains that data so it doesn't re-read every file, making up-to-date checks faster.

open as a page

What is a Gradle Build Scan, and how do you publish one from a build?

level: juniorimportance: must knowfreq 62%
basics
~10 s

A Build Scan is a shareable web report of a build's results. You publish one by adding --scan to any Gradle command; Gradle uploads the data and prints a scan URL.

open as a page

What is the difference between Gradle's configuration phase and execution phase, and why does the distinction matter when a build feels slow?

level: juniorimportance: must knowfreq 70%
basics
~20 s

Configuration builds the task graph by evaluating build scripts; execution runs the selected tasks' actions. A build can be slow because the graph takes long to build (configuration) or because the tasks themselves take long (execution).

open as a page

What does the --dry-run flag do when you run a Gradle build, and when would you use it?

level: juniorimportance: must knowfreq 60%
basics
~10 s

--dry-run makes Gradle print the ordered list of tasks it WOULD run for your requested goal, without actually executing any of them. It's a safe way to preview the task graph.

open as a page

What is the Gradle --profile HTML report and how do you generate one?

level: juniorimportance: must knowfreq 55%
basics
~10 s

Pass --profile to a build (e.g. ./gradlew build --profile). Gradle writes a self-contained HTML report to build/reports/profile/profile-<timestamp>.html showing where build time was spent.

open as a page

You've published a Build Scan for a slow build. How do you use the Timeline tab to find the single slowest task and understand why the overall build took so long?

level: juniorimportance: must knowfreq 60%
basics
~10 s

Open the Build Scan's Timeline tab, sort tasks by duration (longest first), and read the top entry. It shows each task's wall-clock time so you can see which task dominated the build.

open as a page