Featured image of post Accelerating GitHub Actions CI/CD workflows using Caching Featured image of post Accelerating GitHub Actions CI/CD workflows using Caching

Accelerating GitHub Actions CI/CD workflows using Caching

Optimize your GitHub Actions build steps by caching npm modules, pip packages, and Cargo build targets.

Optimizing CI/CD workflow times directly impacts developer productivity and reduces computing expenses. This article shows you how to integrate dependency caching in GitHub Actions, helping you slash compilation and package setup times.

We provide YAML workflow templates for Node.js, Python, and Rust, alongside best practices to ensure optimal cache hits.


1. Why Cache Dependencies in CI/CD?

When a CI agent starts without caching, it spins up a clean container and fetches every dependency from package registries. This introduces several drawbacks:

  1. Inefficient Dev Loops: Developers waste precious minutes waiting for standard libraries to install before testing code.
  2. Network Risks: If npm, PyPI, or crates.io undergoes minor downtime, your build fails due to external network issues.
  3. Execution Costs: On private repositories, GitHub charges you for every active minute. Faster builds directly reduce operations costs.

Caching allows the pipeline to reuse downloaded resources across executions, making subsequent runs execute up to 80% faster.


2. YAML Templates for Major Languages

In 2026, GitHub’s default language setup actions include built-in caching support, making configuration straightforward.

1) Node.js (npm / pnpm / yarn)

Configure the cache property under actions/setup-node:

name: Node.js CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm' # Supports npm, yarn, or pnpm

      - name: Install Packages
        run: npm ci

      - name: Run Tests
        run: npm test

2) Python (pip / poetry)

For Python environments, enable caching using the cache key in actions/setup-python:

name: Python Test Runner

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
          cache: 'pip' # Supports pip, poetry, or pipenv
      - name: Install Dependencies
        run: pip install -r requirements.txt
      - name: Run Linter
        run: flake8 .

3) Rust (Cargo)

Rust compilation is notoriously slow. To cache Cargo dependencies and intermediate build artifacts (the /target directory), use the community standard swatinem/rust-cache:

name: Rust CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust compiler
        uses: actions/setup-rust@v1
      - name: Configure Cargo Cache
        uses: swatinem/rust-cache@v2
      - name: Execute Tests
        run: cargo test

3. Custom Caching and Troubleshooting

For folders not handled by default actions, define them manually using actions/cache:

- name: Cache Custom Files
  uses: actions/cache@v4
  with:
    path: ~/.my-custom-cache
    key: ${{ runner.os }}-custom-${{ hashFiles('**/lockfile.json') }}
    restore-keys: |
      ${{ runner.os }}-custom-
  • key: Unique identifier for the cache. The hashFiles function creates a hash of your lockfiles (package-lock.json, Cargo.lock, etc.). When a lockfile changes, the old cache is invalidated and a fresh one is built.
  • restore-keys: An ordered list of prefix keys to fall back on if an exact cache hit is not found.

Preventing Cache Misses

  1. Commit Lockfiles: Ensure lockfiles are tracked in Git. Without them, hashes fluctuate, causing frequent cache misses.
  2. Track Cache Size: GitHub limits cache storage to 10GB per repository. Once you exceed this limit, GitHub automatically evicts older caches. Exclude unnecessary build artifacts from your cache paths.

4. Summary

Configuring actions caching is one of the easiest ways to optimize your software pipelines. Implementing these changes can save hours of wait time across your team every week. Verify your YAML workflows and integrate caching today.