Skip to content

Let only main write the Gradle cache - #32

Merged
DimazzzZ merged 1 commit into
mainfrom
perf/ci-cache-write-policy
Aug 17, 2026
Merged

DimazzzZ merged 1 commit into
mainfrom
perf/ci-cache-write-policy

Conversation

@DimazzzZ

@DimazzzZ DimazzzZ commented Aug 17, 2026 •

Copy link
Copy Markdown
Owner

Summary

Follow-up to #29, found by measuring the slow CI run you flagged (run 32030544289):

Job Step Time
Plugin Verifier Verify plugin (3 IDEs, pre-#29) 7m27s
Plugin Verifier Post Setup Gradle — uploading cache 1m44s
Test Test (cold cache) 6m13s
Test Post Setup Gradle 32s

#29 fixed the verifier side (one pinned IDE). This fixes the other half, which is systemic.

The cause

cache-read-only was pull_request && head.repo != base repo — i.e. it excluded forks only, so every same-repo PR wrote its own copy of the Gradle home. Measured state:

total: 24.01 GB across 60 entries   (GitHub budget ~10 GB)
refs/heads/main        14 entries
refs/pull/28/merge     18 entries
refs/pull/29/merge     17 entries

Over budget means LRU eviction, so entries were thrown away before they could ever be reused. Every run therefore paid twice: a cold restore and ~2 min of pointless uploading.

The change

PRs are read-only; only pushes to main write. This is the documented setup-gradle pattern, main already holds a full set of entries, and PRs can still restore the default branch's cache. It's also strictly safer — same-repo PRs can no longer poison the shared cache.

Also corrects a comment I added in #29 claiming the extracted IDEs aren't cached and would need their own cache action. They are — setup-gradle covers both the installers in caches/modules-2 and the extracted trees (there's a gradle-transforms-v1 entry, ~1.4 GB). Pinning verification to one IDE is what bounds the size, not any absence of caching. The reasoning in #29's commit message was wrong on that point even though its conclusion (don't add a second cache action) happened to be right.

Test plan

  • YAML validates; both setup-gradle steps now resolve to cache-read-only: ${{ github.event_name == 'pull_request' }}; no stale fork condition remains.
  • On this PR's own run: Post Setup Gradle should be short (no save) instead of 1m44s/32s.
  • After it merges, the first main push reseeds the cache; the run after that should show a warm restore and a materially faster Test step than the 6m13s baseline.

Note the stale refs/pull/* cache entries should be pruned so the next run isn't competing with them for the budget — GitHub reclaims them when PRs close, but not promptly.

Measured on run 32030544289: the Plugin Verifier job spent 1m44s and the test
job 32s in `Post Setup Gradle` — i.e. uploading cache — on top of both runs
starting cold.

The cause was the cache-read-only condition, which excluded forks only, so
every same-repo pull request wrote its own copy of the Gradle home. That put
the repository at 24GB across 60 entries against GitHub's ~10GB per-repo
budget (refs/heads/main=14, refs/pull/28=18, refs/pull/29=17), so entries were
LRU-evicted before they could be reused. Runs therefore paid twice: cold
restores plus ~2min/run of pointless uploading.

Pull requests are now read-only and only pushes to main write, which is the
documented setup-gradle pattern. PRs can still restore the default branch's
cache, and main already holds a full set of entries. It is also strictly
safer, since same-repo PRs can no longer poison the shared cache.

Also correct a comment added in #29 claiming the extracted IDEs are not
cached and would need a cache action of their own. They are: setup-gradle
covers both the installers under caches/modules-2 and the extracted trees
(there is a `gradle-transforms-v1` entry, ~1.4GB). Pinning verification to a
single IDE is what bounds the size, not any absence of caching.
@DimazzzZ DimazzzZ self-assigned this Aug 17, 2026
@DimazzzZ DimazzzZ added type: chore CI, build, deps, config domain: infra CI/CD, build, gradle labels Aug 17, 2026
@DimazzzZ
DimazzzZ merged commit 97ad51c into main Aug 17, 2026
8 of 9 checks passed
@DimazzzZ
DimazzzZ deleted the perf/ci-cache-write-policy branch August 17, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: infra CI/CD, build, gradle type: chore CI, build, deps, config

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant