skip to content

In Gradle's console output, what's the difference between UP-TO-DATE, NO-SOURCE, FROM-CACHE, and a task with no label?

level: middleimportance: should knowfreq 40%

answer

  1. no label = executed
  2. UP-TO-DATE = unchanged inputs
  3. NO-SOURCE = no input files
  4. FROM-CACHE = restored from cache
  5. SKIPPED = onlyIf/disabled

basics

~20 s

No label = the task executed. UP-TO-DATE = skipped because inputs/outputs didn't change. NO-SOURCE = skipped because it had no input files at all. FROM-CACHE = its outputs were restored from the build cache instead of being computed.

solid answer

~50 s

Each task line in `--console=verbose` (or a build scan) carries an outcome label describing why the task did or didn't do work. **No label** means the task ran its actions normally. **UP-TO-DATE** means up-to-date checking found the declared inputs and outputs unchanged since the last run, so the action was skipped and prior outputs reused locally. **NO-SOURCE** means the task is skippable and had zero input source files (e.g., `compileJava` with no `.java` files), so there was nothing to do. **FROM-CACHE** means the task was out of date locally but its output fingerprint matched an entry in the build cache, so Gradle restored the outputs instead of executing. **SKIPPED** appears when an `onlyIf {}` predicate or `enabled = false` turned the task off. Reading these labels is the first step in understanding and tuning incremental performance.

code

bash · 5 lines
bash
$ ./gradlew build --console=verbose
> Task :compileJava UP-TO-DATE
> Task :processTestResources NO-SOURCE
> Task :test FROM-CACHE
> Task :jar

go deeper

for a junior

Recognize that UP-TO-DATE and no-label mean skipped-vs-executed.

for a middle

Differentiate all four outcomes and when each appears.

for a senior

Explain the ordering (up-to-date checked before cache) and use the labels to spot churn.

for a principal

Use outcome distributions across builds as a fleet-wide incrementality/cache-hit health metric.

## Reading task outcomes Gradle annotates each task in the console (use `--console=verbose` to always show labels; the rich console collapses them) and in build scans. The label tells you the *outcome*: ### No label — EXECUTED The task ran its `@TaskAction`/`doLast` logic. Either it was out of date and not cacheable (or cache missed), or it has actions and tracking that required execution. ### UP-TO-DATE Up-to-date checking compared the task's declared inputs and outputs to the recorded history and found no change, so the action was skipped and the **local** outputs from the previous run are reused. This is the central incremental optimization. ### NO-SOURCE The task declared input *source* files but the set was empty, so there is literally nothing to process. Common with `compileJava`/`processResources` when the corresponding source set is empty. Distinct from UP-TO-DATE: UP-TO-DATE has inputs that didn't change; NO-SOURCE has no inputs at all. ### FROM-CACHE The task was **not** up to date locally (or had no local outputs), but it is cacheable and its computed cache key matched a stored entry, so Gradle unpacked the outputs from the build cache rather than recomputing them. Requires the build cache to be enabled and the task `@CacheableTask`. ### SKIPPED An `onlyIf { ... }` predicate evaluated false, or the task was disabled (`enabled = false`). The task was deliberately not run. ## Why the distinction matters When tuning build performance you scan these labels: ``` > Task :compileJava UP-TO-DATE > Task :processTestResources NO-SOURCE > Task :test FROM-CACHE > Task :jar ``` A healthy incremental rebuild is mostly UP-TO-DATE/FROM-CACHE/NO-SOURCE with few executed tasks. Lots of unlabeled (executed) tasks on a no-op rebuild signals churn worth investigating (see up-to-date debugging). Note the ordering of the mechanism: Gradle checks up-to-date **first**; only if out of date and cacheable does it consult the cache, yielding FROM-CACHE. ## Summary table | Label | Meaning | |---|---| | (none) | Executed normally | | UP-TO-DATE | Inputs/outputs unchanged; local outputs reused | | NO-SOURCE | No input source files; nothing to do | | FROM-CACHE | Outputs restored from the build cache | | SKIPPED | onlyIf false / disabled |

  • What's the difference between UP-TO-DATE and NO-SOURCE?
    UP-TO-DATE means the task had inputs that didn't change since last run; NO-SOURCE means the task had no input source files at all, so there was nothing to process.
  • Can a task be both up-to-date and from-cache in the same run?
    No. Gradle checks up-to-date first; if up to date it reports UP-TO-DATE and never consults the cache. FROM-CACHE only happens when the task was out of date locally.

saying these in an interview costs you the question

  • Treating NO-SOURCE as an error — it just means empty inputs.
  • Assuming FROM-CACHE and UP-TO-DATE are interchangeable; they describe different reuse paths.

context