High-performance command-line interface for cache management in CI/CD workflows. Built with Rust for maximum performance and reliability.
curl -sSL https://install.boringcache.com/install.sh | sh
Download the latest release from GitHub Releases:
- Linux AMD64/ARM64
- macOS Intel/ARM64
- Windows AMD64
git clone https://github.com/boringcache/cli.git
cd cli
cargo install --path .
boringcache auth --token your-api-token
# Install (force CDN revalidation to avoid stale script)
curl -sSL -H "Cache-Control: no-cache" -H "Pragma: no-cache" \
https://install.boringcache.com/install.sh | sh
# Save cache entries (tag:path pairs) - workspace format: namespace/workspace
# (only the tag is sent to the API; the path stays local)
boringcache save my-org/my-workspace "node-deps:node_modules,build-cache:target"
# Restore cache entries (tag:path pairs)
# (remote lookups now use tag-only identifiers)
boringcache restore my-org/my-workspace "node-deps:node_modules,build-cache:target"
# Custom compression
boringcache save my-org/my-workspace "rust-release:target" --compression zstd
# Force overwrite existing cache
boringcache save my-org/my-workspace "build-cache:dist" --force
# Save without platform suffix (cross-platform cache)
boringcache save my-org/my-workspace "platform-agnostic:data" --no-platform
# List cache entries
boringcache ls my-workspace
# Delete cache entries
boringcache delete my-workspace "old-cache-key"
# List workspaces
boringcache workspaces
Authenticate with the BoringCache API.
Save cache entries. Use tag:path
format. Only the tag reaches the
BoringCache API; the path is used locally to locate files before upload.
Options:
--compression, -c
: Algorithm (lz4
,zstd
) - auto-selected by default--description
: Description for the cache entry--force
: Force save even if cache entry already exists on server (overwrites existing)--no-platform
: Disable automatic platform suffix (e.g.,-ubuntu-22.04-amd64
)--verbose, -v
: Enable detailed output
Restore cache entries. Path is mandatory - use tag:path
format. When
communicating with the API the CLI now resolves caches by tag alone, while the
path controls where data is extracted locally.
Examples:
# Single restore
boringcache restore my-workspace "node-deps:node_modules"
# Multiple restores
boringcache restore my-workspace "node-deps:node_modules,build-cache:target"
Options:
--all
: Extract all archived paths to current directory--no-platform
: Disable automatic platform suffix (e.g.,-ubuntu-22.04-amd64
)--verbose, -v
: Enable detailed output
List cache entries.
Options:
--limit, -l
: Number of entries (default: 20)--page
: Page number (default: 1)
Delete cache entries.
Options:
--by-tag
: Delete by tags instead of keys
List all workspaces.
Manage configuration (list
, get <key>
, set <key> <value>
).
BORINGCACHE_API_URL
- Override API URLBORINGCACHE_API_TOKEN
- API token (useful for CI)BORINGCACHE_DEFAULT_WORKSPACE
- Set default workspaceBORINGCACHE_COMPRESSION
- Force compression (lz4
,zstd
)BORINGCACHE_OPTIMIZE_FOR
- Optimize for (speed
,size
,bandwidth
)BORINGCACHE_ZSTD_LEVEL
- Set ZSTD compression level (1-22)BORINGCACHE_DEBUG
- Show compression decision reasoning
Override Examples:
# Force LZ4 for maximum speed
export BORINGCACHE_COMPRESSION=lz4
# Force ZSTD for maximum compression
export BORINGCACHE_COMPRESSION=zstd
# Optimize for bandwidth in slow networks
export BORINGCACHE_OPTIMIZE_FOR=bandwidth
# Debug compression decisions
export BORINGCACHE_DEBUG=1
- Early cache hit detection - 1ms response for existing caches (vs 15s+ without optimization)
- Instant UI feedback - Shows progress immediately before network operations
- Zero startup delay - Optimized initialization order eliminates 1-2s hangs
- Preflight validation - Checks permissions and disk space before expensive operations
- Connection pooling - Reuses HTTP connections for multiple operations
The CLI automatically chooses between LZ4 and ZSTD based on:
- System resources (CPU cores, memory, load)
- File characteristics (size, file count)
- Environment context (CI, containers, platform)
Selection Logic:
- Small files (<50MB): LZ4 for speed
- Large files (>500MB) + powerful system: ZSTD for compression
- CI environments + large packages: ZSTD for bandwidth savings
- Resource-constrained systems: LZ4 regardless of size
- High CPU load (>95%): LZ4 to avoid system stress
Adaptive Compression Levels:
- High-end systems (16+ cores, 32GB+ RAM): ZSTD Level 6
- Mid-range systems (8+ cores, 16GB+ RAM): ZSTD Level 4
- Standard systems (4+ cores): ZSTD Level 2
- Resource-constrained: ZSTD Level 1 or LZ4
- SHA256 content verification - Prevents cache poisoning attacks
- Path traversal protection - Safe archive extraction with path validation
- Permission safety - Disables dangerous setuid/setgid permission preservation
- Resource limits - Protects against zip bombs and excessive resource usage
Scenario | System | File Size | Choice | Reason |
---|---|---|---|---|
CI build cache | 4 cores, 8GB | 500MB | LZ4 | Fast extraction priority |
Package distribution | 16 cores, 32GB | 2GB | ZSTD | Worth compression time for downloads |
Container with limits | 2 cores, 4GB | 1GB | LZ4 | Resource constraints |
High CPU load | Any | Any | LZ4 | Avoid additional CPU stress |
- Streaming I/O - Memory-efficient for large files
- Content fingerprinting - Avoids redundant uploads
- Cross-platform - Linux, macOS, Windows (AMD64/ARM64)
- Sub-second startup - <100ms cold start
- Symlink preservation - Maintains symbolic links in archives
name: CI with BoringCache
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
env:
BORINGCACHE_API_TOKEN: ${{ secrets.BORINGCACHE_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
# Install BoringCache CLI
- run: curl -sSL https://install.boringcache.com/install.sh | sh
# Restore cache (fails gracefully if not found)
- run: boringcache restore my-org/my-workspace "node-deps:node_modules"
continue-on-error: true
- run: npm ci
- run: npm test
# Save cache on success
- run: boringcache save my-org/my-workspace "node-deps:node_modules"
if: success()
name: Advanced CI with Multiple Caches
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
env:
BORINGCACHE_API_TOKEN: ${{ secrets.BORINGCACHE_TOKEN }}
BORINGCACHE_OPTIMIZE_FOR: bandwidth # Optimize for CI bandwidth
steps:
- uses: actions/checkout@v4
# Install CLI
- run: curl -sSL https://install.boringcache.com/install.sh | sh
# Multi-language setup
- uses: actions/setup-node@v4
with:
node-version: '20'
- uses: actions/setup-python@v5
with:
python-version: '3.11'
# Restore multiple caches (lightning fast with early hit detection)
- run: |
boringcache restore my-org/project \
"node-deps:node_modules,python-deps:.venv,build-cache:dist"
continue-on-error: true
# Build steps
- run: npm ci && npm run build
- run: python -m pip install -r requirements.txt
- run: python -m pytest
# Save all caches atomically
- run: |
boringcache save my-org/project \
"node-deps:node_modules,python-deps:.venv,build-cache:dist" \
--description "CI build ${{ github.sha }}"
if: success()
Cross-platform binaries are automatically built and released via GitHub Actions:
Trigger Methods:
# 1. Create and push a tag
git tag v1.2.3
git push origin v1.2.3
# 2. Create a GitHub release
# Go to GitHub β Releases β "Draft a new release"
# 3. Manual workflow dispatch
# GitHub β Actions β "Build and Release CLI" β "Run workflow"
Built Platforms:
- Linux AMD64 + ARM64
- macOS Intel + ARM64
- Windows AMD64
# Development build
cargo build
# Release build (optimized)
cargo build --release
# Run tests
cargo test
# Check formatting & linting
cargo fmt -- --check
cargo clippy
By default, BoringCache automatically appends platform-specific suffixes to cache tags to ensure platform isolation. This prevents binary incompatibilities when caches are shared across different operating systems and architectures.
Default Behavior:
# Saved on Ubuntu 22.04 AMD64
boringcache save workspace "deps:node_modules"
# Actual tag: deps-ubuntu-22.04-amd64
# Saved on macOS ARM64
boringcache save workspace "deps:node_modules"
# Actual tag: deps-macos-15-arm64
# Saved on Windows
boringcache save workspace "deps:node_modules"
# Actual tag: deps-windows-2022-amd64
Disabling Platform Suffix:
Use --no-platform
when your cache is platform-independent:
# Platform-agnostic data (configs, documentation, etc.)
boringcache save workspace "config:settings" --no-platform
boringcache restore workspace "config:settings" --no-platform
# Cross-platform JavaScript/TypeScript
boringcache save workspace "js-deps:node_modules" --no-platform
Force Overwriting:
Use --force
to overwrite existing cache entries:
# Update existing cache without checking
boringcache save workspace "build:dist" --force
# Combine with no-platform for cross-platform overwrites
boringcache save workspace "data:files" --force --no-platform
The CLI now uses a consistent tag:path
format for both save and restore operations:
# β
New format (v0.1.0+) - consistent tag:path
boringcache save workspace "node-deps:node_modules"
boringcache restore workspace "node-deps:node_modules"
# β Old format (deprecated) - inconsistent path:tag vs tag:path
boringcache save workspace "node_modules:node-deps" # was path:tag
boringcache restore workspace "node-deps:node_modules" # was tag:path
Benefits:
- Consistent API - Same format for save and restore
- User control - No automatic platform suffix appending
- Predictable - What you save is exactly what you restore
- Privacy - Only the tag is sent to the API; the path never leaves your machine
- Cross-platform - Works identically on all platforms
If upgrading from earlier versions:
- Review your scripts - Change save format from
path:tag
totag:path
- Update CI workflows - Use consistent
tag:path
format throughout - Test thoroughly - Verify cache keys match between save and restore
- Rust - Maximum performance and safety
- Security-first design - SHA256 verification, path traversal protection, resource limits
- Intelligent compression - Auto-selects LZ4/ZSTD based on system capabilities
- Streaming I/O - Memory-efficient for large files
- Early optimization - Cache hit detection before expensive operations
- Cross-platform - Linux, macOS, Windows (AMD64/ARM64)
- No dependencies - Static binaries with no runtime requirements