Cache Optimization
This guide covers advanced cache optimization strategies, performance tuning, and best practices for managing pantry's caching system in production environments.
Cache Architecture
Cache Hierarchy
pantry uses a multi-layered caching approach:
~/.cache/pantry/
├── binaries/
│ ├── packages/ # Package-specific cache
│ │ ├── {domain}-{version}/
│ │ │ ├── package.tar.xz
│ │ │ └── extracted/
│ │ └── metadata.json
│ └── bun/ # Bun-specific optimized cache
│ ├── {version} # Direct binary cache
│ └── checksums.json
└── temp/ # Temporary download cache
└── {download-id}/
Cache Key Strategy
Cache keys are generated using a deterministic approach:
- Package Cache:
{domain}-{version}(e.g.,nodejs.org-20.0.0) - Bun Cache:
{version}(e.g.,1.2.3) - Temporary Cache:
{timestamp}-{hash}for downloads in progress
Environment Selection Cache
pantry also maintains a lightweight shell-side cache for environment activation. It stores:
- a persistent marker for fast-path activation, and
- a
.deps_fingerprintfile inside the environment with the dependency fingerprint used to select it.
On directory change, pantry validates fast-path cache with two signals:
- "Cache invalid: dependency newer than cache" (dep file mtime > cache mtime)
- "Cache invalid: fingerprint mismatch" (computed fingerprint != stored fingerprint)
When either triggers, pantry skips fast-path and refreshes the environment selection, ensuring the correct versions are active.
Performance Optimization
Cache Hit Optimization
1. Version Pinning Strategy
# Instead of using latest (cache miss on updates)
pantry install node@latest
# Use specific versions for better cache hits
pantry install node@20.0.0 python@3.11.5
2. Batch Operations
# Efficient: Single operation, shared cache lookups
pantry install node@20 python@3.11 bun@1.2.3
# Less efficient: Multiple operations, repeated cache checks
pantry install node@20
pantry install python@3.11
pantry install bun@1.2.3
3. Environment Consistency
# deps.yaml - Use exact versions for cache consistency
dependencies:
node: 20.0.0
python.org: 3.11.5
bun.sh: 1.2.3
Cache Warming Strategies
Pre-populate Common Packages
# !/bin/bash
# cache-warm.sh - Pre-populate cache with common packages
COMMON_PACKAGES=(
"node@20.0.0"
"node@18.19.0"
"python@3.11.5"
"python@3.10.12"
"bun@1.2.3"
"go@1.21.5"
)
for package in "${COMMON_PACKAGES[@]}"; do
echo "Warming cache for $package..."
pantry install "$package" --cache-only 2>/dev/null || true
done
CI/CD Cache Strategy
# .github/workflows/cache-strategy.yml
name: Optimized Cache Strategy
jobs:
setup:
runs-on: ubuntu-latest
steps:
- name: Cache pantry packages
uses: actions/cache@v3
with:
path: ~/.cache/pantry
key: pantry-${{ runner.os }}-${{ hashFiles('deps.yaml') }}
restore-keys: |
pantry-${{ runner.os }}-
- name: Install dependencies
run: |
pantry install
Cache Size Management
Monitoring Cache Growth
# !/bin/bash
# cache-monitor.sh - Monitor cache size and growth
cache_size() {
du -sh ~/.cache/pantry 2>/dev/null | cut -f1 || echo "0B"
}
cache_files() {
find ~/.cache/pantry -type f 2>/dev/null | wc -l || echo "0"
}
echo "Cache size: $(cache_size)"
echo "Cache files: $(cache_files)"
# Detailed breakdown
echo "Package cache: $(du -sh ~/.cache/pantry/binaries/packages 2>/dev/null | cut -f1 || echo '0B')"
echo "Bun cache: $(du -sh ~/.cache/pantry/binaries/bun 2>/dev/null | cut -f1 || echo '0B')"
Automated Cache Cleanup
# !/bin/bash
# cache-cleanup.sh - Automated cache maintenance
MAX_CACHE_SIZE_MB=1000
CACHE_DIR="$HOME/.cache/pantry"
# Check current cache size
current_size=$(du -sm "$CACHE_DIR" 2>/dev/null | cut -f1 || echo "0")
if [ "$current_size" -gt "$MAX_CACHE_SIZE_MB" ]; then
echo "Cache size ($current_size MB) exceeds limit ($MAX_CACHE_SIZE_MB MB)"
# Clean old packages first (keep recent versions)
find "$CACHE_DIR/binaries/packages" -type d -mtime +30 -exec rm -rf {} + 2>/dev/null
# If still too large, clear entire cache
new_size=$(du -sm "$CACHE_DIR" 2>/dev/null | cut -f1 || echo "0")
if [ "$new_size" -gt "$MAX_CACHE_SIZE_MB" ]; then
echo "Clearing entire cache..."
pantry cache:clear --force
fi
fi
Selective Cache Retention
# !/bin/bash
# selective-cleanup.sh - Keep only essential cached packages
KEEP_PACKAGES=(
"nodejs.org-20.0.0"
"python.org-3.11.5"
"bun.sh-1.2.3"
)
# Clear cache but preserve essential packages
temp_dir=$(mktemp -d)
for package in "${KEEP_PACKAGES[@]}"; do
if [ -d "$HOME/.cache/pantry/binaries/packages/$package" ]; then
cp -r "$HOME/.cache/pantry/binaries/packages/$package" "$temp_dir/"
fi
done
# Clear cache and restore essential packages
pantry cache:clear --force
mkdir -p "$HOME/.cache/pantry/binaries/packages"
for package in "${KEEP_PACKAGES[@]}"; do
if [ -d "$temp_dir/$package" ]; then
mv "$temp_dir/$package" "$HOME/.cache/pantry/binaries/packages/"
fi
done
rm -rf "$temp_dir"
Advanced Cache Strategies
Multi-Environment Cache Sharing
Shared Cache Setup
# Setup shared cache for team/CI environments
export pantry_CACHE_DIR="/shared/cache/pantry"
mkdir -p "$pantry_CACHE_DIR"
# Symlink to shared cache
rm -rf ~/.cache/pantry
ln -s "$pantry_CACHE_DIR" ~/.cache/pantry
Cache Synchronization
# !/bin/bash
# sync-cache.sh - Synchronize cache across environments
REMOTE_CACHE="user@server:/shared/cache/pantry/"
LOCAL_CACHE="$HOME/.cache/pantry/"
# Download shared cache
rsync -av --delete "$REMOTE_CACHE" "$LOCAL_CACHE"
# Upload local cache additions
rsync -av "$LOCAL_CACHE" "$REMOTE_CACHE"
Cache Validation and Integrity
Checksum Verification
# !/bin/bash
# verify-cache.sh - Verify cache integrity
CACHE_DIR="$HOME/.cache/pantry/binaries/packages"
for package_dir in "$CACHE_DIR"/_; do
if [ -d "$package_dir" ]; then
package_name=$(basename "$package_dir")
# Check if package archive exists and is valid
if [ -f "$package_dir/package.tar.xz" ]; then
if ! tar -tf "$package_dir/package.tar.xz" >/dev/null 2>&1; then
echo "Corrupted cache for $package_name, removing..."
rm -rf "$package_dir"
fi
fi
fi
done
Cache Repair
# !/bin/bash
# repair-cache.sh - Repair corrupted cache entries
corrupted_packages=()
# Detect corrupted packages
while IFS= read -r -d '' package_dir; do
package_name=$(basename "$package_dir")
if [ -f "$package_dir/package.tar.xz" ]; then
if ! tar -tf "$package_dir/package.tar.xz" >/dev/null 2>&1; then
corrupted_packages+=("$package_name")
rm -rf "$package_dir"
fi
fi
done < <(find "$HOME/.cache/pantry/binaries/packages" -maxdepth 1 -type d -print0)
# Re-download corrupted packages
for package in "${corrupted_packages[@]}"; do
echo "Re-caching $package..."
# Extract package name and version
domain=$(echo "$package" | cut -d'-' -f1-2)
version=$(echo "$package" | cut -d'-' -f3-)
pantry install "$domain@$version" --force-download 2>/dev/null || true
done
Performance Monitoring
Cache Performance Metrics
# !/bin/bash
# cache-metrics.sh - Collect cache performance metrics
CACHE_DIR="$HOME/.cache/pantry"
METRICS_FILE="/tmp/pantry-cache-metrics.json"
# Collect metrics
cache_size_bytes=$(du -sb "$CACHE_DIR" 2>/dev/null | cut -f1 || echo "0")
cache_files=$(find "$CACHE_DIR" -type f 2>/dev/null | wc -l || echo "0")
package_count=$(find "$CACHE_DIR/binaries/packages" -maxdepth 1 -type d 2>/dev/null | wc -l || echo "0")
bun_versions=$(find "$CACHE_DIR/binaries/bun" -type f 2>/dev/null | wc -l || echo "0")
# Calculate cache hit rate (requires instrumentation)
cache_hits=$(grep "cache hit" ~/.pantry/logs/install.log 2>/dev/null | wc -l || echo "0")
cache_misses=$(grep "cache miss" ~/.pantry/logs/install.log 2>/dev/null | wc -l || echo "0")
total_requests=$((cache_hits + cache_misses))
if [ "$total_requests" -gt 0 ]; then
hit_rate=$(echo "scale=2; $cache_hits _ 100 / $total_requests" | bc)
else
hit_rate="0"
fi
# Generate metrics JSON
cat > "$METRICS_FILE" << EOF
{
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"cache_size_bytes": $cache_size_bytes,
"cache_files": $cache_files,
"package_count": $package_count,
"bun_versions": $bun_versions,
"cache_hit_rate": $hit_rate,
"cache_hits": $cache_hits,
"cache_misses": $cache_misses
}
EOF
echo "Metrics saved to $METRICS_FILE"
cat "$METRICS_FILE"
Performance Benchmarking
# !/bin/bash
# benchmark-cache.sh - Benchmark cache performance
PACKAGES=("node@20.0.0" "python@3.11.5" "bun@1.2.3")
echo "Benchmarking cache performance..."
# Clear cache for clean test
pantry cache:clear --force >/dev/null 2>&1
# Benchmark cold cache (first install)
echo "Cold cache performance:"
for package in "${PACKAGES[@]}"; do
start_time=$(date +%s.%N)
pantry install "$package" >/dev/null 2>&1
end_time=$(date +%s.%N)
duration=$(echo "$end_time - $start_time" | bc)
echo " $package: ${duration}s"
done
# Benchmark warm cache (reinstall)
echo "Warm cache performance:"
for package in "${PACKAGES[@]}"; do
# Uninstall first
pantry uninstall "$package" >/dev/null 2>&1
start_time=$(date +%s.%N)
pantry install "$package" >/dev/null 2>&1
end_time=$(date +%s.%N)
duration=$(echo "$end_time - $start_time" | bc)
echo " $package: ${duration}s"
done
Best Practices
Development Workflow
- Use Specific Versions: Pin exact versions in
deps.yamlfor consistent cache hits - Batch Operations: Install multiple packages in single commands
- Regular Monitoring: Check cache size weekly with
pantry cache:clear --dry-run - Selective Cleanup: Use
--keep-cachewhen resetting environments
Production Deployment
- Pre-warm Cache: Cache common packages before deployment
- Shared Cache: Use shared cache directories in containerized environments
- Cache Validation: Implement integrity checks in CI/CD pipelines
- Size Limits: Set up automated cleanup when cache exceeds limits
Team Collaboration
- Standardized Versions: Use team-wide
deps.yamlfiles - Cache Sharing: Share cache in development environments
- Documentation: Document cache strategies in project README
- Monitoring: Set up team-wide cache performance monitoring
Troubleshooting
Common Cache Issues
Cache Corruption
# Symptoms: Installation failures, corrupted archives
# Solution: Clear and rebuild cache
pantry cache:clear --force
pantry install your-packages
Disk Space Issues
# Symptoms: "No space left on device" errors
# Solution: Clean cache and monitor size
pantry cache:clear --dry-run # Check size first
pantry cache:clear --force # Clean if needed
Permission Problems
# Symptoms: Permission denied errors
# Solution: Fix cache directory permissions
sudo chown -R $(whoami) ~/.cache/pantry
chmod -R 755 ~/.cache/pantry
Performance Issues
Slow Cache Lookups
# Check cache directory structure
find ~/.cache/pantry -type f | wc -l
# If too many files, consider cleanup
pantry cache:clear --force
Network vs Cache Performance
# Compare download vs cache performance
time pantry install node@20.0.0 # First time (download)
pantry uninstall node@20.0.0
time pantry install node@20.0.0 # Second time (cache)
Related Documentation
- Cache Management - Basic cache management commands
- Performance Optimization - General performance tuning
- Cross-platform Compatibility - Platform-specific considerations