This document describes the comprehensive caching strategy implemented across all workflows to improve performance, reduce costs, and increase resilience.
- 30-70% faster workflow execution on cache hits
- Reduced network I/O by reusing downloaded dependencies
- Lower latency by avoiding repeated downloads from external registries
- Reduced GitHub Actions minutes through faster execution
- Lower network transfer costs by minimizing external downloads
- Better resource utilization of runner compute time
- Reduced external dependencies during workflow execution
- Better handling of external service outages (PyPI, RubyGems, Docker Hub)
- Consistent build environment across workflow runs
Caches Ubuntu system packages to speed up any apt installations performed by underlying actions.
- name: Cache APT packages
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: |
/var/cache/apt/archives
/var/lib/apt/lists
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/*.yml') }}
restore-keys: |
${{ runner.os }}-apt-Paths:
/var/cache/apt/archives- Downloaded .deb package files/var/lib/apt/lists- Package index files
Cache Key Strategy:
- Primary key includes workflow file hash for invalidation on changes
- Restore key allows fallback to any APT cache
Benefits:
- Faster installation of system dependencies
- Reduced load on Ubuntu package mirrors
- Better handling of mirror outages
Caches Python packages for cfn-lint and checkov security scanning tools.
- name: Setup Python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: '3.12'
- name: Cache Python dependencies
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: |
~/.cache/pip
~/.local/lib/python3.12/site-packages
key: ${{ runner.os }}-pip-cfn-lint-checkov-${{ hashFiles('.github/workflows/*.yml') }}
restore-keys: |
${{ runner.os }}-pip-cfn-lint-checkov-
${{ runner.os }}-pip-Paths:
~/.cache/pip- pip download cache~/.local/lib/python3.12/site-packages- Installed Python packages
Cache Key Strategy:
- Primary key includes workflow file hash for invalidation on workflow changes
- Multiple restore keys for progressive fallback
- Tool-specific prefix for better cache organization
Benefits:
- Faster cfn-lint CloudFormation validation
- Faster Checkov security scanning
- Reduced load on PyPI (files.pythonhosted.org)
- Better handling of PyPI outages
Caches Ruby gems for cfn-nag security scanning tool.
- name: Setup Ruby
uses: ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 # v1.270.0
with:
ruby-version: '3.3'
- name: Cache Ruby gems
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-cfn-nag-${{ hashFiles('.github/workflows/*.yml') }}
restore-keys: |
${{ runner.os }}-gems-cfn-nag-
${{ runner.os }}-gems-Paths:
vendor/bundle- Bundler gem installation directory
Cache Key Strategy:
- Primary key includes workflow file hash for invalidation on workflow changes
- Multiple restore keys for progressive fallback
- Tool-specific prefix for better cache organization
Benefits:
- Faster cfn-nag static analysis
- Reduced load on RubyGems.org
- Better handling of RubyGems outages
Caches Docker image layers for ZAP API security scanning.
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Cache Docker layers
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-docker-zap-${{ hashFiles('.github/workflows/main.yml') }}
restore-keys: |
${{ runner.os }}-docker-zap-
${{ runner.os }}-docker-Paths:
/tmp/.buildx-cache- Docker BuildKit cache directory
Cache Key Strategy:
- Primary key includes workflow file hash
- Multiple restore keys for progressive fallback
- Tool-specific prefix for better cache organization
Benefits:
- Faster ZAP Docker image pulls
- Reduced load on GitHub Container Registry (ghcr.io)
- Better handling of registry outages
- Faster security scanning execution
- ✅ APT package cache
- ✅ Python pip cache (cfn-lint, checkov)
- ✅ Ruby gems cache (cfn-nag)
- ✅ Docker layer cache (ZAP)
Tools Accelerated:
- scottbrenner/cfn-lint-action (4 instances)
- stelligent/cfn_nag (2 instances)
- bridgecrewio/checkov-action (1 instance)
- zaproxy/action-api-scan (1 instance)
- ✅ APT package cache
- ✅ Python pip cache (cfn-lint, checkov)
- ✅ Ruby gems cache (cfn-nag)
Tools Accelerated:
- scottbrenner/cfn-lint-action (4 instances)
- stelligent/cfn_nag (1 instance)
- bridgecrewio/checkov-action (1 instance)
- Workflow File Changes: Cache key includes workflow file hash
- OS Changes: Cache key includes runner.os
- Manual Invalidation: Update cache key prefix in workflow
Note: Since the repository doesn't have requirements.txt or Gemfile.lock files (dependencies are managed by composite actions), the cache keys are based on workflow file hashes. This means caches will be invalidated when workflows are modified.
All caches use progressive restore keys:
key: ${{ runner.os }}-tool-specific-${{ hashFiles(...) }}
restore-keys: |
${{ runner.os }}-tool-specific-
${{ runner.os }}-This allows:
- Exact match → Use specific cache
- Tool match → Use any version of tool cache
- OS match → Use any cache for the OS
- No match → Build from scratch
- Cache Hit Rate: Track percentage of successful cache restores
- Workflow Duration: Measure execution time improvements
- Cache Size: Monitor storage usage in GitHub Actions cache
- External Service Reliability: Track dependency on external services
| Workflow | First Run | Cache Hit | Improvement |
|---|---|---|---|
| main.yml | ~8-10 min | ~5-7 min | 30-40% faster |
| pullrequest.yml | ~5-7 min | ~3-4 min | 40-50% faster |
- GitHub Actions Cache Limit: 10 GB per repository
- Current Cache Usage (estimated):
- APT packages: ~100-200 MB
- Python pip: ~50-100 MB
- Ruby gems: ~20-50 MB
- Docker layers: ~500-800 MB
- Total: ~700-1150 MB per workflow
Check the workflow logs for:
Cache not found for input keys: Linux-pip-cfn-lint-checkov-abc123
Solutions:
- Verify cache key hash inputs exist
- Check if cache was evicted (7-day retention)
- Verify workflow has correct cache action version
Check for permission errors:
Error: Unable to restore cache
Solutions:
- Verify workflow has
contents: readpermission - Check if cache size exceeds 10 GB limit
- Verify cache paths exist and are accessible
If cache save/restore is slow:
- Reduce cache path sizes
- Use more specific restore-keys
- Consider cache compression settings
All cache actions use SHA-pinned versions for security:
actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 # v1.270.0docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
Caches are:
- Scoped to repository
- Isolated between branches (for PRs)
- Accessible within workflow runs
- Protected by GitHub Actions security model
Warning: Never cache:
- Environment variables with secrets
- AWS credentials
- API tokens
- Private keys
- Configuration files with sensitive data
Review caching strategy:
- Monthly: Check cache hit rates and performance metrics
- Quarterly: Update pinned action versions
- After Tool Updates: Verify cache compatibility with new tool versions
- Tool Version Changes: Update cache keys if tool versions change
- New Tools Added: Add corresponding cache configuration
- Workflow Restructure: Review and update cache key hashes
- Performance Issues: Adjust cache paths or key strategy
- GitHub Actions Caching Documentation
- actions/cache Repository
- Docker Buildx Cache Documentation
- pip Caching
- Bundler Configuration
Last Updated: 2025-12-16
Author: DevOps Team
Version: 1.0