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?
answer
- settings.gradle(.kts), not build.gradle
- buildCache { remote<HttpBuildCache> }
- initialization phase
- before projects/tasks
- --build-cache toggles, settings sets policy
basics
~20 sIn 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.
solid answer
~40 sThe push/pull split lives in the `buildCache {}` block of **`settings.gradle(.kts)`**, not in a project's `build.gradle(.kts)`. Inside it you declare the `remote<HttpBuildCache>` and set `isPush`/`isEnabled`: ```kotlin buildCache { remote<HttpBuildCache> { url = uri("https://cache.example.com/cache/") isPush = System.getenv("CI") != null } } ``` It belongs in settings because the build cache is part of the build's infrastructure: Gradle reads it during the **initialization phase** (settings evaluation), before the configuration phase builds the task graph and before any task executes. That ordering guarantees the cache is connected and the push policy decided before the first cacheable task looks for a hit. You can still override on/off per run with `--build-cache`/`--no-build-cache`, but the push policy itself is the settings code.
code
kotlin · 8 lines// settings.gradle.kts (NOT build.gradle.kts)
buildCache {
remote<HttpBuildCache> {
url = uri("https://cache.example.com/cache/")
isEnabled = true
isPush = System.getenv("CI") != null
}
}go deeper
Knows the block is in settings.gradle and roughly that it's set up early.
Can name the initialization phase and the isPush/isEnabled knobs.
Explains why settings (build-wide infra) and how overrides interact with the policy.
Standardizes settings-level cache configuration (often via a convention/settings plugin) across many repos.
## The three Gradle phases A Gradle build runs in three phases: 1. **Initialization** — Gradle reads `settings.gradle(.kts)`, decides which projects make up the build, and configures build-wide infrastructure including the **build cache**. 2. **Configuration** — each project's `build.gradle(.kts)` runs, building the task graph. 3. **Execution** — the requested tasks run; cacheable tasks consult the cache for hits and may push outputs. ## Why the cache config is in settings The `buildCache {}` block must be in `settings.gradle(.kts)` because the cache is a property of the *whole build*, established in the **initialization** phase before any project (and any task) exists. If it lived in a project script, it would be configured too late and inconsistently across a multi-project build. So the push/pull decision — `isPush` and `isEnabled` on the `local {}` and `remote {}` caches — is settings-level code. ```kotlin // settings.gradle.kts buildCache { local { isEnabled = true } remote<HttpBuildCache> { url = uri("https://cache.example.com/cache/") isEnabled = true // pull for everyone isPush = System.getenv("CI") != null // push only on CI } } ``` ## Two knobs - `isEnabled` — participate in this cache (read). - `isPush` — allowed to write new entries. For the CI-seed pattern you keep `isEnabled = true` everywhere and flip `isPush` true only on CI. ## Command-line and property overrides The master on/off switch for caching at runtime is `--build-cache` / `--no-build-cache`, or the persistent `org.gradle.caching=true` in `gradle.properties`. These toggle whether caching happens at all; they don't replace the push/pull *policy*, which is the conditional logic in settings. So: settings code expresses the policy; the flag/property expresses per-run enablement. ## Common mistake Putting `buildCache {}` in a project `build.gradle(.kts)` — Gradle will error or ignore it because by configuration time it's too late to set up build-wide cache infrastructure. Always settings.
- What happens if you put the buildCache block in a project's build.gradle.kts?It is too late — the cache is configured during initialization (settings), so a project-script block is ignored or errors. It must live in settings.gradle(.kts).
- Does --no-build-cache change the push/pull policy?No. It disables caching entirely for that run. The push/pull policy is the conditional isPush logic in settings; the flag is just a global on/off.
saying these in an interview costs you the question
- Putting buildCache configuration in build.gradle.kts.
- Thinking the cache is set up during the configuration or execution phase rather than initialization.