Gradle remote build cache

A Gradle remote build cache, with no server to run

Point Gradle's built-in HttpBuildCache at a CloudRepo repository. CI uploads task outputs, and any machine with a token can restore those tasks from the cache instead of running them again.

settings.gradle.kts

buildCache {
    remote<HttpBuildCache> {
        url = uri("https://[org-id].mycloudrepo.io/repositories/[repo-name]/")
        isPush = System.getenv("CI") != null
        credentials {
            username = System.getenv("CLOUDREPO_USERNAME")
            password = System.getenv("CLOUDREPO_TOKEN")
        }
    }
}

Set it up in three steps

The full guide, with the Groovy block, is in the documentation.

  1. 1

    Create a repository for the cache

    Create a Maven repository that holds only the cache, then turn Overwrite Protection off on it. A new repository refuses a second upload of a key it already holds with 409 Conflict. Gradle then logs "The remote build cache was disabled during the build due to errors." and stops using the remote cache for the rest of that build, while the build still succeeds. With Overwrite Protection off, the repeated upload is accepted.

  2. 2

    Create two repository tokens

    A Read + write token for CI, which fills the cache, and a Read only token for developer machines, which only read it. An upload with a read-only token is refused with 403 Forbidden. The username is the email address of the account that created the token, and the password is the token.

  3. 3

    Add the cache to settings.gradle.kts

    Gradle uploads only where the CI environment variable is set, so developer builds read from the cache and upload nothing. Turn the cache on with org.gradle.caching=true in gradle.properties, or pass --build-cache.

    buildCache {
        remote<HttpBuildCache> {
            url = uri("https://[org-id].mycloudrepo.io/repositories/[repo-name]/")
            isPush = System.getenv("CI") != null
            credentials {
                username = System.getenv("CLOUDREPO_USERNAME")
                password = System.getenv("CLOUDREPO_TOKEN")
            }
        }
    }

What you get

Gradle's own client
HttpBuildCache is built into Gradle. There is no plugin to add and no cache server to run: the repository stores each entry and returns it byte for byte.
Uploads from CI only
push is on only where CI is set. Developer machines read with a read-only token and never write to the cache.
A credential you can scope
A repository token reaches only the repositories you choose, can be read only, and can be revoked on its own, without changing anyone’s password.
Groovy or Kotlin DSL
The docs show the same block for settings.gradle and settings.gradle.kts. Both were tested with Gradle 9.7.1.

Frequently asked questions

Can a CloudRepo repository be my Gradle build cache server?
Yes. A hosted Maven repository with Overwrite Protection turned off works as the backend for Gradle's built-in HttpBuildCache: a first build uploads its task outputs, and a clean build on another machine restores those tasks FROM-CACHE.
Why does Overwrite Protection have to be off?
Gradle uploads a key that already exists when tasks run again, for example with --rerun-tasks or when two jobs miss the same key. A protected repository answers that upload with 409 Conflict, and Gradle turns its remote cache off for the rest of the build. The build still succeeds, so only the log shows it.
Can developers use the cache without uploading to it?
Yes. Give developer machines a Read only token and set push only where CI is set. Their builds read entries CI uploaded and never write. An upload with a read-only token is refused with 403 Forbidden.
Do cache entries expire?
No. Entries are kept until you delete them: nothing expires them today. They count toward your plan’s storage like any other file.
Does cache traffic count toward my plan?
Yes. Cache uploads and downloads count toward your plan’s monthly transfer allowance. If you exceed your monthly transfer allowance, we reach out first. Nothing is throttled, no build ever stops, and there are no automatic charges. Occasional spikes are simply fine. Sustained overage is billed at $120 per additional TB, always rounded down in your favor (2.9 TB over = 2 TB billed = $240). Storage growth is a prorated one-click plan upgrade, not per-GB fees.

Put your Gradle build cache on CloudRepo

Create the cache repository, two tokens and one settings block.