> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/continuous-integration/3.0/use-harness-ci/use-harness-ci/caching-ci-data/save-restore-cache-in-harness.md).

# Save and Restore Cache from Harness

Caching enables data sharing across steps, now natively supported with Harness Cloud Storage

Harness CI provides built-in steps to save and restore build cache, helping you reduce build times by reusing dependencies and artifacts across executions.

Previously, Harness-managed storage for caching was only available via [Cache Intelligence](/continuous-integration/3.0/use-harness-ci/use-harness-ci/caching-ci-data/cache-intelligence.md), for customers running on Harness Cloud.

Unlike Cache Intelligence, where Harness automatically restores cache at the start of a stage and saves it at the end, the new **Save Cache to Harness** and **Restore Cache from Harness** steps give you full flexibility. You can insert them anywhere in your stage, for example, after dynamically generating a cache key or before executing specific build commands.

{% hint style="info" %}
Currently, the new **Save Cache to Harness** and **Restore Cache from Harness** steps are only available for stages running on **Harness Cloud** build infrastructure. This feature can be used alongside [Cache Intelligence](/continuous-integration/3.0/use-harness-ci/use-harness-ci/caching-ci-data/cache-intelligence.md)
{% endhint %}

### Save Cache Step <a href="#save-cache-step" id="save-cache-step"></a>

The `SaveCache` step allows you to select specific files or directories to cache to Harness-managed storage.

#### YAML Configuration <a href="#yaml-configuration" id="yaml-configuration"></a>

To configure the Save Cache step in Harness, use the `SaveCache` step type.

```yaml
- step:
    type: SaveCache
    name: Save Cache to Harness
    identifier: Save_Cache_to_Harness
    spec:
      key: "harness-cache-{{ checksum 'pom.xml' }}"
      sourcePaths:
        - /root/.m2/repository
      archiveFormat: Tar
      override: true
```

#### Explanation <a href="#explanation" id="explanation"></a>

| **Property**    | **Type**                               | **Description**                                                                                                                                                                                                |
| --------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`           | Fixed Value, Runtime Input, Expression | **Required**. A unique key to identify the cache. It is highly recommended to use expressions (like checksums) to create dynamic keys based on your dependencies (e.g., cache-{{ checksum "build.gradle" }} ). |
| `sourcePaths`   | Fixed Value, Runtime Input, Expression | **Required**. A list of paths to the files or directories you want to cache.                                                                                                                                   |
| `archiveFormat` | Fixed Value, Runtime Input, Expression | **Optional**. The archiving format to use. Supported values are Tar, Gzip, and Zstd. Default is Tar.                                                                                                           |
| `override`      | Fixed Value, Runtime Input, Expression | **Optional**. Boolean value. If set to true, it overrides an existing cache with the same key. Default is false.                                                                                               |

### Restore Cache Step <a href="#restore-cache-step" id="restore-cache-step"></a>

The `RestoreCache` step retrieves artifacts stored by a previous SaveCache step using the specified key.

#### YAML Configuration <a href="#yaml-configuration" id="yaml-configuration"></a>

```yaml
- step:
    type: RestoreCache
    name: Restore Cache from Harness
    identifier: Restore_Cache_from_Harness
    spec:
      key: "harness-cache-{{ checksum 'pom.xml' }}"
      archiveFormat: Tar
```

### Output Variables <a href="#output-variables" id="output-variables"></a>

The Restore Cache step produces output variables that indicate whether the cache was successfully restored. You can use these variables in subsequent steps to make decisions (for example, skipping dependency installation if the cache was hit).

| **Output variable** | **Type** | **Description**                                                                                             |
| ------------------- | -------- | ----------------------------------------------------------------------------------------------------------- |
| `cacheHit`          | String   | `true` if a cache matching the step's `key` was found and restored. `false` if no matching cache was found. |

#### Example Usage of Output Variable <a href="#example-usage-of-output-variable" id="example-usage-of-output-variable"></a>

You can reference the output variable using the syntax `<+steps.stepIdentifier.output.outputVariables.cacheHit>`.

```yaml
- step:
    type: Run
    name: Install Dependencies
    identifier: Install_Dependencies
    spec:
      shell: Sh
      # Only run install if cache was NOT restored
      command: |
        if [ "<+steps.Restore_Cache_from_Harness.output.outputVariables.cacheHit>" == "false" ]; then
          mvn clean install
        else
          echo "Cache restored, skipping install"
        fi
```

### Best Practices <a href="#best-practices" id="best-practices"></a>

To maximize the efficiency of caching in your pipelines, consider the following best practices:

**Use Dynamic Keys based on Lock Files**: Avoid static cache keys. Instead, use checksums of dependency lock files (such as pom.xml, package-lock.json, yarn.lock, or go.sum). This ensures that the cache is automatically invalidated and refreshed only when your dependencies actually change.

* Good Key: `npm-cache-{{ checksum "package-lock.json" }}`
* Bad Key: npm-cache-v1

**Cache Dependencies, Not Build Artifacts**: These steps are designed for dependencies (like \~/.m2/repository or node\_modules) that rarely change between builds. Do not use caching for build artifacts that need to be passed reliably between stages; use standardized artifact management for that purpose.

**Include OS in Keys for Multi-Platform Pipelines**: If your pipeline runs on varying infrastructure (e.g., sometimes Linux, sometimes macOS), include the operating system in your cache key. Native dependencies often cannot be shared across different operating systems.

Example: `{{ matrix.os }}-maven-cache-{{ checksum "pom.xml" }}`

**Minimize Cache Scope**: Only cache the specific directories required. Caching overly large or root directories can lead to slow save/restore times that negate the speed benefits of caching.

{% @harness-feedback/feedback %}
