Skip to main content

Implementing Caching Strategies

1. Caching Dependencies

Cache Key Values Description
key actions/cache@v3 Cache key pattern to use for storing and retrieving cache
path node_modules Directory to cache or restore
restore-keys node_modules- Alternative cache keys to use if the primary key does not match

Example: Caching Node.js Dependencies

steps:
  - name: Cache node modules
    uses: actions/cache@v3
    id: cache-npm
    with:
      path: ~/.npm
      key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-node-
Note: The hashFiles function ensures that the cache is invalidated when dependencies change.

Example: Caching Multiple Paths

steps:
  - name: Cache multiple paths
    uses: actions/cache@v3
    with:
      path: |
        ~/.npm
        ~/.cache
      key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

2. Defining Cache Keys

Property Description Example
path File or directory to cache node_modules/
key Cache key to use for storing and retrieving cache node-modules-${{ hashFiles('**/package-lock.json') }}
restore-keys Alternative keys to try if the primary key doesn't exist node-modules-

Example: Defining Cache Keys

steps:
  - name: Cache node modules
    uses: actions/cache@v3
    with:
      path: node_modules/
      key: modules-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        modules-

3. Using Restore Keys

Property Description Values
restore-keys Defines a list of keys to use for restoring cache ["cache-v1-{{ checksum("package-lock.json") }}", "cache-v1-"]

Example: Using restore-keys in a job

steps:
  - name: Restore cache
    uses: actions/cache/restore@v3
    with:
      path: |
        ~/.npm
        node_modules
      key: cache-v1-{{ checksum("package-lock.json") }}
      restore-keys: |
        cache-v1-
        cache-
Note: Restore keys allow fallback to a previous cache if the primary key does not match.

4. Caching Node Modules

Option Values Notes
uses actions/cache@v3 Cache action for GitHub Actions
key node-modules-${{ hashFiles('**/package-lock.json') }} Unique key for cache
restore-keys node-modules- Fallback keys for cache restoration

Example: Caching Node Modules

steps:
  - name: Cache node modules
    uses: actions/cache@v3
    id: cache-modules
    with:
      path: ~/.npm
      key: node-modules-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        node-modules-
Note: The hashFiles function ensures cache invalidation when dependencies change.

5. Caching Python Packages

Option Values Notes
uses actions/cache@v3 Cache action for GitHub Actions
key pip-${{ hashFiles('**/requirements.txt') }} Cache key using file hash
restore-keys pip- Restore keys for fallback

Example: Caching Python Dependencies

name: Cache Python Packages
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Cache pip dependencies
        uses: actions/cache@v3
        id: cache-pip
        with:
          path: ~/.cache/pip
          key: pip-${{ hashFiles('**/requirements.txt') }}
      - name: Install dependencies
        if: steps.cache-pip.outputs.cache-hit != 'true'
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
Note: The hashFiles function ensures that the cache is invalidated when dependencies change.
Warning: Ensure that requirements.txt is in the correct location for accurate caching.

6. Caching Maven Dependencies

Option Values Notes
path **/target Directory to cache
key maven-${{ hashFiles('**/pom.xml') }} Cache key with hash of pom.xml
restore-keys maven- Alternative keys to restore from

Example: Caching Maven Dependencies

steps:
  - name: Cache Maven dependencies
    uses: actions/cache@v3
    with:
      path: ~/.m2/repository
      key: maven-${{ hashFiles('**/pom.xml') }}
      restore-keys: |
        maven-
Note: The cache key should include the hash of pom.xml to ensure dependencies are correctly cached and restored.

7. Caching Gradle Dependencies

Option Values Notes
uses actions/cache@v3 Cache action for GitHub Actions
path ~/.gradle/caches Gradle cache directory to cache
key gradle-${{ hashFiles('**/*.gradle') }}-${{ hashFiles('**/gradle-wrapper.properties') }} Unique cache key based on Gradle files
restore-keys gradle- Fallback keys for cache restoration

Example: Caching Gradle Dependencies

steps:
  - name: Cache Gradle dependencies
    uses: actions/cache@v3
    with:
      path: ~/.gradle/caches
      key: gradle-${{ hashFiles('**/*.gradle') }}-${{ hashFiles('**/gradle-wrapper.properties') }}
      restore-keys: gradle-
Note: The cache key should be unique to avoid conflicts. Using hashFiles ensures that the cache is invalidated when Gradle files change.

8. Caching Go Modules

Option Values Notes
go-modules-cache go mod download Downloads Go modules to local cache
go-build-cache go build -a Builds Go binaries with cache enabled

Example: Caching Go Modules in GitHub Actions

name: Go Build with Cache
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.23"

      - name: Cache Go modules
        uses: actions/cache@v4
        with:
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

      - name: Build
        run: go build -v ./...

9. Setting Cache Paths

Option Values Description
path string | string[] Path(s) to cache or restore. Supports glob patterns.
key string Cache key used to restore and save the cache.
restore-keys string[] Alternative keys to use for restoring cache if the primary key does not match.

Example: Caching Node.js Dependencies

steps:
  - uses: actions/checkout@v4
  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'
  - name: Cache Node Modules
    uses: actions/cache@v3
    with:
      path: |
        **/node_modules
        !**/node_modules/.cache
      key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-node-
Note: The path can include multiple directories or use glob patterns to match files. Use ! to exclude specific paths.

10. Handling Cache Misses

Example: Cache Miss Detection and Fallback

name: Build with Cache Fallback
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install Dependencies
        run: npm ci
        if: ${{ steps.cache.outputs.cache-hit != 'true' }}

      - name: Build Project
        run: npm run build
Property Description Usage
steps.<step-name>.outputs.cache-hit Indicates whether the cache was hit or missed Use in conditional logic with if
cache-key Key used to identify cache entries Must be unique per dependency set
Note: When cache-hit is false, it means the cache was not found and dependencies must be reinstalled.
Warning: If cache keys are not unique, cache misses can lead to incorrect builds or outdated dependencies.

11. Invalidating Cache

Cache Key Invalidation Method Description
cache-key-v1 invalidate Manual invalidation of cache by key
cache-key-v2 invalidate Cache invalidated with new version key

Example: Invalidating Cache with Key

steps:
  - name: Invalidate Cache
    run: |
      gh cache delete --key cache-key-v1
Note: Cache invalidation is required when dependencies or build configurations change to ensure that outdated artifacts do not cause unexpected behavior.

12. Managing Cache Size

Option Values Description
cache.size 100MB Maximum size of the cache to retain
cache.ttl 7d Time-to-live for cache entries (in days)
cache.strategy LRU Cache eviction strategy (e.g., LRU, FIFO)

Example: Configuring Cache Size in Workflow

name: Cache Size Example
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Cache Dependencies
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
Note: Cache size limits are enforced at the workflow level and can be adjusted via environment variables or job-specific configurations.

13. Using Cache Across Branches

Option Values Notes
cache.key actions/cache/save@v3 Key to use for saving and restoring cache
cache.path node_modules Path to cache (e.g., node_modules, ~/.npm)
cache.restore-keys node_modules- Keys to try restoring cache from (fallbacks)

Example: Caching Across Branches

steps:
  - name: Cache node modules
    uses: actions/cache@v3
    with:
      path: node_modules
      key: ${{ runner.os }}-build-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-build-
Note: Cache keys are unique per branch and workflow. To share cache across branches, use a common prefix or restore-keys pattern.

Was this article helpful?