// Copyright (C) 2024 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[directory_layout]]
= Gradle-managed Directories and Caches
:keywords: gradle, user, home, project, root, directory, gradle_home, gradle_user_home, cache, caches

Gradle uses two main directories to perform and manage its work and stores several caches under them:

- <<#dir:gradle_user_home>>
- <<#dir:project_root>>
- <<#dir:caches>>

image::author-gradle-2.png[]

[[dir:gradle_user_home]]
== 1. Gradle User Home directory

By default, the Gradle User Home (`~/.gradle` or `C:\Users\<USERNAME>\.gradle`) stores global configuration properties, initialization scripts, caches, and log files.

It can be set with the environment variable `GRADLE_USER_HOME`.

TIP: Not to be confused with the `GRADLE_HOME`, the optional installation directory for Gradle.

It is roughly structured as follows:

[source,text]
----
├── caches              // <1>
├── daemon              // <2>
├── init.d              // <3>
├── jdks                // <4>
├── wrapper
│   └── dists           // <5>
└── gradle.properties   // <6>
----
<1> <<#dir:caches, Caches>>.
<2> Registry and logs of the <<gradle_daemon.adoc#gradle_daemon, Gradle Daemon>>.
<3> Global <<init_scripts.adoc#init_scripts, initialization scripts>>.
<4> JDKs downloaded by the <<toolchains.adoc#sec:provisioning, toolchain support>>.
<5> Distributions downloaded by the <<gradle_wrapper.adoc#gradle_wrapper,Gradle Wrapper>>.
<6> Global <<build_environment.adoc#sec:gradle_configuration_properties,Gradle configuration properties>>.

[[dir:project_root]]
== 2. Project Root directory

The project root directory contains all source files from your project.

It also contains files and directories Gradle generates, such as `.gradle` and `build`.

While the former are usually checked into source control, the latter are transient files Gradle uses to support features like incremental builds.

The anatomy of a typical project root directory looks as follows:

[source,text]
----
├── .gradle                 // <1>
├── build                   // <2>
├── gradle
│   └── wrapper             // <3>
├── gradle.properties       // <4>
├── gradlew                 // <5>
├── gradlew.bat             // <5>
├── settings.gradle.kts     // <6>
├── subproject-one          // <7>
|   └── build.gradle.kts    // <8>
├── subproject-two          // <7>
|   └── build.gradle.kts    // <8>
└── ⋮
----
<1> Project-specific <<#dir:caches,cache>> directory generated by Gradle.
<2> The build directory of this project into which Gradle generates all build artifacts.
<3> Contains the JAR file and configuration of the <<gradle_wrapper.adoc#gradle_wrapper,Gradle Wrapper>>.
<4> Project-specific <<build_environment.adoc#sec:gradle_configuration_properties,Gradle configuration properties>>.
<5> Scripts for executing builds using the <<gradle_wrapper.adoc#gradle_wrapper,Gradle Wrapper>>.
<6> The project's <<settings_file_basics.adoc#sec:settings_file_script, settings file>> where the list of subprojects is defined.
<7> Usually, a project is organized into one or multiple subprojects.
<8> Each subproject has its own Gradle build script.

[[dir:caches]]
== 3. Caches

Gradle uses several on-disk caches to make repeat builds faster.
These caches live under the directories described in <<#dir:gradle_user_home, Gradle User Home>> and <<#dir:project_root, Project Root>>.
In most cases they do not require manual management.
Gradle creates, uses, and cleans them automatically.

[[dir:caches:version_specific]]
=== Version-specific caches

These caches live under `caches/<gradle-version>/` in the Gradle User Home and are tied to a specific Gradle release.
They are recreated on first use of that Gradle version.

[cols="1,4"]
|===
| Directory | Contents

| `<version>/generated-gradle-jars`
| JARs that Gradle generates on first use of the Gradle version.

| `<version>/kotlin-dsl`
| Compiled Kotlin DSL scripts and accessors.

| `<version>/scripts`
| Compiled Groovy DSL scripts.
|===

[[dir:caches:shared]]
=== Shared caches

These caches live directly under `caches/` in the Gradle User Home and are shared across Gradle versions.
The trailing number in each directory name is the on-disk format version; see <<#dir:caches:format_versions, Format versions in cache directory names>>.

[cols="1,4"]
|===
| Directory | Contents

| `build-cache-1`
| Local <<build_cache.adoc#build_cache, Build Cache>> entries: task outputs keyed by input hashes.

| `jars-9`
| Instrumented JARs produced by Gradle's classpath instrumentation.

| `modules-2`
| Downloaded module dependencies (POMs, JARs, metadata).
See <<dependency_caching.adoc#sec:dependency-cache, Dependency caching>>.

| `transforms-3`
| Outputs of <<artifact_transforms.adoc#artifact-transforms, artifact transforms>>.
|===

[[dir:caches:project_local]]
=== Project-local caches

These caches live under `.gradle/` in the project root and are specific to a single project.

[cols="1,4"]
|===
| Directory | Contents

| `.gradle/<version>`
| Version-specific build state for incremental build (snapshots of task inputs and outputs from the previous build).

| `.gradle/configuration-cache`
| <<configuration_cache_enabling.adoc#config_cache:usage:invalidate, Configuration Cache>> state for this project: the serialized task graph, configuration inputs, and metadata used to skip the configuration phase on subsequent builds.
|===

[[dir:caches:format_versions]]
=== Format versions in cache directory names

Several caches use a trailing format version in their directory name (for example, `modules-2`, `jars-9`, `transforms-3`, `build-cache-1`).
The number changes when Gradle changes the on-disk layout for that cache.

When multiple format versions of the same cache exist on disk (for example, both `transforms-3` and `transforms-4`), the older one is left behind from a previous Gradle version and is cleaned up after the inactivity threshold.
Only the current format is being written by the current Gradle version.

[[dir:gradle_user_home:cache_cleanup]]
=== Cleanup of caches and distributions

Gradle automatically cleans its caches in both the Gradle User Home and the project directory.

By default, the cleanup runs in the background when the Gradle daemon is stopped or shut down.

If using `--no-daemon`, it runs in the foreground after the build session.

==== Gradle User Home cleanup

The following cleanup strategies are applied periodically (by default, once every 24 hours):

- Version-specific caches in all `caches/<GRADLE_VERSION>/` directories are checked for whether they are still in use.
+
If not, directories for release versions are deleted after 30 days of inactivity, and snapshot versions after 7 days.
- Shared caches in `caches/` (e.g., `jars-*`) are checked for whether they are still in use.
+
If no Gradle version still uses them, they are deleted.
- Files in shared caches used by the current Gradle version in `caches/` (e.g., `jars-9` or `modules-2`) are checked for when they were last accessed.
+
Depending on whether the file can be recreated locally or downloaded from a remote repository, it will be deleted after 7 or 30 days, respectively.
- Gradle distributions in `wrapper/dists/` are checked for whether they are still in use, i.e., whether there's a corresponding version-specific cache directory.
+
Unused distributions are deleted.
- Daemon log files in `daemon/<GRADLE_VERSION>/` directories are checked for their last modification time.
+
Log files older than 14 days are automatically deleted to prevent the daemon directory from growing indefinitely.

[[dir:project_root:cache_cleanup]]
==== Project cache cleanup

From version 4.10 onwards, Gradle automatically cleans the project-specific cache directory.

After building the project, version-specific cache directories in `.gradle/{gradleVersion}/` are checked periodically (at most, every 24 hours) to determine whether they are still in use.
They are deleted if they haven't been used for 7 days.

[[dir:gradle_user_home:configure_cache_cleanup]]
==== Configuring cleanup of caches and distributions

The retention periods of the various caches can be configured.

Caches are classified into six categories:

1. *Released wrapper distributions:* Distributions and related version-specific caches corresponding to released versions (e.g., `4.6.2` or `8.0`).
+
Default retention for unused versions is 30 days.
2. *Snapshot wrapper distributions:* Distributions and related version-specific caches corresponding to snapshot versions (e.g. `7.6-20221130141522+0000`).
+
Default retention for unused versions is 7 days.
3. *Downloaded resources:* Shared caches downloaded from a remote repository (e.g., cached dependencies).
+
Default retention for unused resources is 30 days.
4. *Created resources:* Shared caches that Gradle creates during a build (e.g., artifact transforms).
+
Default retention for unused resources is 7 days.
5. *Build cache:* The local build cache (e.g., build-cache-1).
+
Default retention for unused build cache entries is 7 days.
6. *Daemon logs:* Log files from Gradle Daemon processes in `daemon/<GRADLE_VERSION>/` directories.
+
Default retention for daemon logs is 14 days.

The retention period for each category can be configured independently via an <<init_scripts.adoc#init_scripts,init script>> in the Gradle User Home:

====
include::sample[dir="snippets/reference/runtime-configuration/cacheRetention/kotlin",files="gradleUserHome/init.d/cache-settings.init.gradle.kts"]
include::sample[dir="snippets/reference/runtime-configuration/cacheRetention/groovy",files="gradleUserHome/init.d/cache-settings.init.gradle"]
====

The frequency at which cache cleanup is invoked is also configurable.

There are three possible settings:

1. *DEFAULT:* Cleanup is performed periodically in the background (currently once every 24 hours).
2. *DISABLED:* Never cleanup Gradle User Home.
+
This is useful in cases where Gradle User Home is ephemeral or delaying cleanup is desirable until an explicit point.
3. *ALWAYS:* Cleanup is performed at the end of each build session.
+
This is useful in cases where it's desirable to ensure that cleanup has occurred before proceeding.
+
However, this performs cache cleanup during the build (rather than in the background), which can be expensive, so this option should only be used when necessary.

To disable cache cleanup:

====
include::sample[dir="snippets/reference/runtime-configuration/disableCacheCleanup/kotlin",files="gradleUserHome/init.d/cache-settings.init.gradle.kts"]
include::sample[dir="snippets/reference/runtime-configuration/disableCacheCleanup/groovy",files="gradleUserHome/init.d/cache-settings.init.gradle"]
====

NOTE: Cache cleanup settings can only be configured via init scripts and should be placed under the `init.d` directory in Gradle User Home.
This effectively couples the configuration of cache cleanup to the Gradle User Home those settings apply to and limits the possibility of different conflicting settings from different projects being applied to the same directory.

[[dir:gradle_user_home:multi_version_cache_cleanup]]
==== Multiple versions of Gradle sharing a Gradle User Home

It is common to share a single Gradle User Home between multiple versions of Gradle.

As stated above, caches in Gradle User Home are version-specific.
Different versions of Gradle will perform maintenance on only the version-specific caches associated with each version.

On the other hand, some caches are shared between versions (e.g., the dependency artifact cache or the artifact transform cache).

Beginning with Gradle version 8.0, the cache cleanup settings can be configured to custom retention periods.
However, older versions have fixed retention periods (7 or 30 days, depending on the cache).
These shared caches could be accessed by versions of Gradle with different settings to retain cache artifacts.

This means that:

- If the retention period is _not_ customized, all versions that perform cleanup will have the same retention periods. There will be no effect due to sharing a Gradle User Home with multiple versions.
- If the retention period is customized for Gradle versions greater than or equal to version 8.0 to use retention periods _shorter_ than the previously fixed periods, there will also be no effect.
+
The versions of Gradle aware of these settings will cleanup artifacts earlier than the previously fixed retention periods, and older versions will effectively not participate in the cleanup of shared caches.
- If the retention period is customized for Gradle versions greater than or equal to version 8.0 to use retention periods _longer_ than the previously fixed periods, the older versions of Gradle may clean the shared caches earlier than what is configured.
+
In this case, if it is desirable to maintain these shared cache entries for newer versions for longer retention periods, they will not be able to share a Gradle User Home with older versions. They will need to use a separate directory.

Another consideration when sharing the Gradle User Home with versions of Gradle before version 8.0 is that the DSL elements to configure the cache retention settings are unavailable in earlier versions, so this must be accounted for in any init script shared between versions.
This can easily be handled by conditionally applying a version-compliant script.

NOTE: The version-compliant script should reside somewhere other than the `init.d` directory (such as a sub-directory), so it is not automatically applied.

To configure cache cleanup in a version-safe manner:

====
include::sample[dir="snippets/reference/runtime-configuration/multiVersionCacheRetention/kotlin",files="gradleUserHome/init.d/cache-settings.init.gradle.kts"]
include::sample[dir="snippets/reference/runtime-configuration/multiVersionCacheRetention/groovy",files="gradleUserHome/init.d/cache-settings.init.gradle"]
====

Version-compliant cache configuration script:

====
include::sample[dir="snippets/reference/runtime-configuration/multiVersionCacheRetention/kotlin",files="gradleUserHome/init.d/gradle8/cache-settings.init.gradle.kts"]
include::sample[dir="snippets/reference/runtime-configuration/multiVersionCacheRetention/groovy",files="gradleUserHome/init.d/gradle8/cache-settings.init.gradle"]
====

[[dir:gradle_user_home:cache_marking]]
=== Cache marking

Beginning with Gradle version 8.1, Gradle supports marking caches with a `CACHEDIR.TAG` file.

It follows the format described in https://bford.info/cachedir/[the Cache Directory Tagging Specification].
The purpose of this file is to allow tools to identify the directories that do not need to be searched or backed up.

By default, the directories `caches`, `wrapper/dists`, `daemon`, and `jdks` in the Gradle User Home are marked with this file.

[[dir:gradle_user_home:configure_cache_marking]]
==== Configuring cache marking

The cache marking feature can be configured via an init script in the Gradle User Home:

====
include::sample[dir="snippets/reference/runtime-configuration/cacheMarking/kotlin",files="gradleUserHome/init.d/cache-settings.init.gradle.kts"]
include::sample[dir="snippets/reference/runtime-configuration/cacheMarking/groovy",files="gradleUserHome/init.d/cache-settings.init.gradle"]
====

NOTE: Cache marking settings can only be configured via init scripts and should be placed under the `init.d` directory in Gradle User Home. This effectively couples the configuration of cache marking to the Gradle User Home to which those settings apply and limits the possibility of different conflicting settings from different projects being applied to the same directory.
