---
title: "Build tool cache"
description: "Use with_tool_cache to transparently back Gradle, Bazel, Turborepo, and Xcode build caches with a CircleCI-managed remote cache."
doc_version: "unversioned"
last_updated: "2026-09-10"
---

> For the complete documentation index, see [llms.txt](https://circleci.com/docs/llms.txt)

# Build tool cache Beta

Build tool caching is in beta on CircleCI Cloud. The feature is still evolving, so you may encounter bugs or changes to behavior. There is no additional cost to use it beyond standard [Cache Storage Usage](https://circleci.com/docs/guides/optimize/persist-data/#managing-network-and-storage-usage).

Use the [`with_tool_cache`](https://circleci.com/docs/reference/configuration-reference/#withtoolcache) step to back a build tool’s own remote cache with a CircleCI-managed cache backend. For example, this can back Gradle’s build cache, Bazel’s remote cache, or Xcode’s Swift/Clang compilation cache. This removes the need to hand-roll a [`save_cache`/`restore_cache`](https://circleci.com/docs/guides/optimize/caching/) pair for tool-specific build outputs, and works the same way across executors.

## How it works

`with_tool_cache` wraps the steps you give it and automatically sets up and tears down a remote cache for the named `tool`:

1.  Starts a local cache server in the background.
    
2.  Configures `tool` to point at that cache server as its remote cache.
    
3.  Runs your wrapped steps.
    
4.  Stops the cache server, regardless of whether your steps passed or failed.
    

You do not need to install or configure anything else. The cache server and per-tool configuration are already available on CircleCI’s execution environments.

## How this differs from save\_cache/restore\_cache

The `save_cache`/`restore_cache` steps take an **eager, bulk** approach: each write saves an entire directory as a single immutable blob under a key. If a single file in that directory changes, the next run saves the whole directory again under a new key. Successive caches end up nearly identical to each other.

`with_tool_cache` takes a **lazy, granular** approach instead. The build tool’s remote cache stores and fetches individual entries as needed. A small change adds only a small amount of new data instead of duplicating the entire cache.

This distinction matters more as a cache grows:

*   With a small cache, bulk caching can perform just as well, since there is only one archive to transfer.
    
*   As a cache grows to hold more entries, granular caching pulls ahead. Bulk caching keeps writing new copies of the same large cache that are nearly identical to the previous one.
    

Two practical benefits follow from this:

*   **Reduced storage use**: A small change adds a small new entry to the remote cache instead of duplicating the whole cache under a new key. Bulk caching, by contrast, tends to accumulate multiple large caches that are nearly identical to each other and use storage until they expire.
    
*   **Less configuration**: `with_tool_cache` requires no cache key design, checksum templates, or key rotation. You do not choose what to cache, build a key, or bump a version prefix to force a clean cache.
    

In internal benchmarks, a clean build using `with_tool_cache` completed about 90% faster than the same build with no cache at all. Actual results depend on the size of your build’s cache and how often it changes.

In a separate benchmark on a large, real-world iOS codebase (WordPress-iOS), `with_tool_cache` with `tool: xcode` cut median clean-build time by about 29% versus a build with no cache. Xcode’s compilation cache is object-level (compiler outputs keyed on source content), not task-level like Gradle’s or Bazel’s. The speedup is smaller as a result, but still meaningful for large native codebases.

## Supported tools

`with_tool_cache` currently supports the following values for `tool`:

Tool What gets cached

`gradle`

Gradle’s remote build cache (task outputs). You still manage the module/dependency cache separately with [`save_cache`/`restore_cache`](https://circleci.com/docs/guides/optimize/caching/#gradle-java).

`bazel`

Bazel’s remote cache.

`turborepo`

Turborepo’s remote cache.

`xcode`

Xcode’s Swift/Clang compilation cache (object-level compiler outputs), enabled by pointing xcodebuild’s compilation cache build settings at the cache server. You still manage CocoaPods/Swift Package Manager dependency caches separately with [\`save\_cache/`restore_cache`](https://circleci.com/docs/guides/optimize/caching/#xcode).

## Quickstart

The following examples show how to use the `with_tool_cache` step for each supported tool.

The `with_tool_cache` works on all executors. Put `checkout` before the `with_tool_cache` step, not inside it.

<Tabs>
<Tab title="Gradle">

```yaml
jobs:
  build:
    docker:
      - image: cimg/base:current # use any image with Gradle installed
    steps:
      - checkout
      - with_tool_cache:
          tool: gradle
          steps:
            - run: ./gradlew build
```

</Tab>
<Tab title="Bazel">

```yaml
jobs:
  build:
    docker:
      - image: cimg/base:current # use any image with Bazel installed
    steps:
      - checkout
      - with_tool_cache:
          tool: bazel
          steps:
            - run: bazel build //...
```

</Tab>
<Tab title="Turborepo">

```yaml
jobs:
  build:
    docker:
      - image: cimg/base:current # use any image with Turborepo installed
    steps:
      - checkout
      - with_tool_cache:
          tool: turborepo
          steps:
            - run: turbo run build
```

</Tab>
<Tab title="Xcode">

`with_tool_cache` starts a compilation cache server and exposes its address to your steps as `COMPILATION_CACHE_REMOTE_SERVICE_PATH` (a `unix://` socket URL). Pass the socket path, stripped of its `unix://` prefix, to `xcodebuild` along with the compilation cache build settings:

```yaml
jobs:
  build:
    macos:
      xcode: 26.6.0
    steps:
      - checkout
      - with_tool_cache:
          tool: xcode
          steps:
            - run:
                name: xcodebuild build
                command: |
                  sock="${COMPILATION_CACHE_REMOTE_SERVICE_PATH#unix://}"
                  xcodebuild build \
                    -workspace MyApp.xcworkspace \
                    -scheme "MyApp" \
                    -destination 'generic/platform=iOS Simulator' \
                    COMPILATION_CACHE_REMOTE_SERVICE_PATH="$sock" \
                    COMPILATION_CACHE_ENABLE_PLUGIN=YES \
                    SWIFT_ENABLE_COMPILE_CACHE=YES \
                    CLANG_ENABLE_COMPILE_CACHE=YES \
                    SWIFT_ENABLE_EXPLICIT_MODULES=YES \
                    SWIFT_USE_INTEGRATED_DRIVER=YES \
                    CLANG_ENABLE_MODULES=YES \
                    COMPILATION_CACHE_ENABLE_INTEGRATED_QUERIES=YES \
                    COMPILATION_CACHE_ENABLE_DETACHED_KEY_QUERIES=YES
```

Compilation caching requires Xcode’s Swift/Clang compile cache support. Check that your Xcode version and toolchain support the `SWIFT_ENABLE_COMPILE_CACHE` and `CLANG_ENABLE_COMPILE_CACHE` build settings before adopting this in CI.

</Tab>
</Tabs>

## Use with dependency caching

The `with_tool_cache` step only manages the build tool’s own remote/task-output cache. It does not replace dependency caching. For example, with Gradle, `with_tool_cache` handles the Gradle build cache, but a separate [`save_cache`/`restore_cache`](https://circleci.com/docs/guides/optimize/caching/#gradle-java) pair still caches `~/.gradle/caches/modules-2` (the downloaded dependencies). The two mechanisms are complementary: one caches what Gradle downloads, the other caches what Gradle builds.

The same applies to Xcode: `with_tool_cache` with `tool: xcode` handles the compilation cache, but you still need a separate [`save_cache`/`restore_cache`](https://circleci.com/docs/guides/optimize/caching/#xcode) pair (or equivalent) for CocoaPods' or Swift Package Manager’s downloaded dependencies.

## See also

*   [`with_tool_cache` Configuration Reference](https://circleci.com/docs/reference/configuration-reference/#withtoolcache)
    
*   [Caching Dependencies](https://circleci.com/docs/guides/optimize/caching/)
    
*   [Docker Layer Caching](https://circleci.com/docs/guides/optimize/docker-layer-caching/)
    
*   [Optimization Reference](https://circleci.com/docs/guides/optimize/optimizations/)