Terraform & OpenTofu Cache Cleanup on Mac -- Free 5-20GB of Disk Space

A complete guide to finding and safely cleaning Terraform provider plugins, module caches, Terragrunt data, and state artifacts on macOS

Published July 18, 2025 • 10 min read • by bysiber

If you work with Infrastructure as Code, you know the story: every terraform init downloads provider plugins, every module source gets cached, and Terragrunt creates full copies of everything. Before you know it, your Mac has 5-20GB or more consumed by Terraform-related files scattered across dozens of directories.

This guide covers every Terraform and OpenTofu cache location on macOS, how to measure them, and how to clean them safely -- without breaking your infrastructure workflows.

Where Does Terraform Store Data on macOS?

DirectoryWhat It StoresTypical Size
.terraform/ (per project)Downloaded provider plugins & modules200 MB - 2 GB each
~/.terraform.d/Plugin cache, credentials, CLI config1-5 GB
.terragrunt-cache/Terragrunt module copies with providers2-15 GB
~/.terraform.d/plugin-cache/Shared plugin cache (if configured)500 MB - 3 GB
terraform.tfstate*State files (if local backend)1-100 MB
~/.config/opentofu/OpenTofu configuration100-500 MB
.terraform.lock.hclProvider version locks<1 MB
⚠ The Hidden Cost: Each .terraform/ directory contains a full copy of every provider binary your project uses. The AWS provider alone is ~350MB. If you have 10 projects using AWS, that's 3.5GB just in duplicate AWS provider binaries.

Step 1: Audit Your Terraform Disk Usage

# Find ALL .terraform directories and their sizes
find ~ -name ".terraform" -type d -not -path "*/.*/.terraform" 2>/dev/null | \
    while read d; do du -sh "$d" 2>/dev/null; done | sort -rh | head -20

# Global Terraform config/cache
du -sh ~/.terraform.d/ 2>/dev/null
du -sh ~/.terraform.d/plugin-cache/ 2>/dev/null
du -sh ~/.terraform.d/plugins/ 2>/dev/null

# Find Terragrunt caches
find ~ -name ".terragrunt-cache" -type d 2>/dev/null | \
    while read d; do du -sh "$d" 2>/dev/null; done | sort -rh | head -20

# OpenTofu directories
du -sh ~/.config/opentofu/ 2>/dev/null

# Total damage estimate
echo "=== Total Terraform/IaC Disk Usage ==="
echo -n ".terraform dirs: "; find ~ -name ".terraform" -type d 2>/dev/null -exec du -sk {} + | awk '{sum+=$1} END{print sum/1024 " MB"}'
echo -n ".terragrunt-cache: "; find ~ -name ".terragrunt-cache" -type d 2>/dev/null -exec du -sk {} + | awk '{sum+=$1} END{print sum/1024 " MB"}'
echo -n "~/.terraform.d/: "; du -sk ~/.terraform.d/ 2>/dev/null | awk '{print $1/1024 " MB"}'

Step 2: Enable the Plugin Cache (Prevent Duplicates)

Before cleaning, the single most impactful thing you can do is enable Terraform's plugin cache. This stores one copy of each provider version and creates symlinks instead of downloading duplicates:

# Create the cache directory
mkdir -p ~/.terraform.d/plugin-cache

# Create or edit ~/.terraformrc
cat > ~/.terraformrc << 'EOF'
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
plugin_cache_may_break_dependency_lock_file = true
EOF

# Or set via environment variable
export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
# Add to your ~/.zshrc or ~/.bashrc for persistence
✓ Huge Savings: The plugin cache typically reduces disk usage by 60-80% on machines with multiple Terraform projects. Instead of 10 copies of the AWS provider (3.5GB), you store just one (350MB).

Step 3: Clean .terraform Directories

The .terraform/ directory in each project is safe to delete -- it's recreated by terraform init:

# Clean a single project
cd your-terraform-project
rm -rf .terraform/
terraform init    # Re-downloads providers and modules

# Clean ALL .terraform directories at once
find ~/Projects -name ".terraform" -type d -exec rm -rf {} + 2>/dev/null

# Safer: only clean .terraform dirs older than 30 days
find ~/Projects -name ".terraform" -type d -mtime +30 -exec rm -rf {} + 2>/dev/null

# Preview what would be cleaned (dry run)
find ~/Projects -name ".terraform" -type d -mtime +30 -exec du -sh {} + 2>/dev/null | sort -rh
ℹ Note: Deleting .terraform/ does NOT delete your state files or .terraform.lock.hcl. It only removes cached provider binaries and module sources. You'll need to run terraform init before your next plan or apply.

Step 4: Clean Terragrunt Cache

Terragrunt's caching is particularly aggressive -- it creates a full copy of each module including all provider plugins:

# Check total Terragrunt cache size
find ~ -name ".terragrunt-cache" -type d -exec du -sh {} + 2>/dev/null | sort -rh

# Clean all Terragrunt caches
find ~ -name ".terragrunt-cache" -type d -exec rm -rf {} + 2>/dev/null

# Or use Terragrunt's built-in command (v0.45+)
terragrunt run-all clean

# Clean only in specific environments
find ~/infra/staging -name ".terragrunt-cache" -exec rm -rf {} +
find ~/infra/dev -name ".terragrunt-cache" -exec rm -rf {} +
⚠ Terragrunt Tip: After cleaning, combine the plugin cache (TF_PLUGIN_CACHE_DIR) with Terragrunt to prevent the cache from re-bloating. This is the single most effective combination for managing IaC disk usage.

Step 5: Clean Global Terraform Data

# The global config directory
du -sh ~/.terraform.d/

# Clean old plugin versions from shared cache
ls ~/.terraform.d/plugin-cache/registry.terraform.io/ 2>/dev/null

# Remove old provider versions (keep only latest)
# Example: clean hashicorp/aws versions older than current
ls -la ~/.terraform.d/plugin-cache/registry.terraform.io/hashicorp/aws/ 2>/dev/null

# Clean global plugins (legacy format, Terraform < 0.13)
rm -rf ~/.terraform.d/plugins/

# Clean credential helpers cache
rm -rf ~/.terraform.d/credentials.tfrc.json  # Only if using terraform login

Step 6: OpenTofu-Specific Cleanup

If you've migrated to OpenTofu, it stores data in slightly different locations:

# OpenTofu config
du -sh ~/.config/opentofu/ 2>/dev/null

# OpenTofu uses the same .terraform/ directory in projects
# but has its own global config path:
du -sh ~/.terraform.d/ 2>/dev/null

# Set plugin cache for OpenTofu too
export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
# Or in ~/.tofurc:
# plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

# Clean OpenTofu lock files if switching from Terraform
find ~/Projects -name ".terraform.lock.hcl" -exec rm {} +
# Then: tofu init -upgrade

Step 7: Clean Terraform State Artifacts

# Find local state files (should be using remote backend)
find ~ -name "terraform.tfstate" -type f 2>/dev/null | head -20
find ~ -name "terraform.tfstate.backup" -type f -exec du -sh {} + 2>/dev/null

# Clean backup state files (keep the current state!)
find ~/Projects -name "terraform.tfstate.backup" -delete

# Find crash logs
find ~ -name "crash.log" -path "*terraform*" -exec du -sh {} + 2>/dev/null
find ~ -name "crash.log" -path "*terraform*" -delete
⚠ NEVER delete terraform.tfstate without a backup. If you're using local state, this file is the only record of what Terraform manages. Always use a remote backend (S3, GCS, Azure Blob, Terraform Cloud) for production infrastructure.

The Complete Terraform Cleanup Script

#!/bin/bash
echo "=== Terraform/OpenTofu Disk Usage Audit ==="
echo ""

# .terraform directories
tf_count=$(find ~ -name ".terraform" -type d 2>/dev/null | wc -l | tr -d ' ')
tf_size=$(find ~ -name ".terraform" -type d -exec du -sk {} + 2>/dev/null | awk '{sum+=$1} END{printf "%.1f", sum/1024}')
echo ".terraform directories: $tf_count found, ${tf_size}MB total"

# Terragrunt cache
tg_count=$(find ~ -name ".terragrunt-cache" -type d 2>/dev/null | wc -l | tr -d ' ')
tg_size=$(find ~ -name ".terragrunt-cache" -type d -exec du -sk {} + 2>/dev/null | awk '{sum+=$1} END{printf "%.1f", sum/1024}')
echo ".terragrunt-cache: $tg_count found, ${tg_size}MB total"

# Global config
echo "~/.terraform.d/: $(du -sh ~/.terraform.d/ 2>/dev/null | cut -f1)"
echo "Plugin cache: $(du -sh ~/.terraform.d/plugin-cache/ 2>/dev/null | cut -f1)"

# State files
state_count=$(find ~ -name "terraform.tfstate*" -type f 2>/dev/null | wc -l | tr -d ' ')
echo "State files found: $state_count"

echo ""
echo "=== Recommendations ==="
echo "1. Enable plugin cache: mkdir -p ~/.terraform.d/plugin-cache"
echo "2. Add to ~/.terraformrc: plugin_cache_dir = \"\$HOME/.terraform.d/plugin-cache\""
echo "3. Clean inactive projects: rm -rf .terraform/ && terraform init"
echo "4. Clean Terragrunt: find . -name '.terragrunt-cache' -exec rm -rf {} +"
echo "5. Use ClearDisk for visual overview: https://github.com/bysiber/cleardisk"

Skip the Manual Audit -- Use ClearDisk

ClearDisk is a free, open-source macOS menu bar app that automatically finds and measures all your Terraform provider caches, Terragrunt cache directories, and every other developer cache in one clean dashboard.

Download ClearDisk Free on GitHub

How Much Space Can You Recover?

ActionSpace RecoveredRisk Level
Clean .terraform/ in inactive projects1-10 GBNone -- terraform init restores
Clean .terragrunt-cache/2-15 GBNone -- regenerated on next run
Enable plugin cache (prevents duplicates)3-10 GB ongoingNone -- transparent optimization
Clean old provider versions from cache500 MB - 2 GBLow -- re-downloads on demand
Delete state backups10-500 MBLow -- backups only
Clean crash logs<10 MBNone -- diagnostic only
✓ Total Potential Savings: Enabling the plugin cache + cleaning old .terraform/ and .terragrunt-cache/ directories typically recovers 5-20GB on machines with multiple IaC projects.

Preventing Future Cache Bloat

  1. Always enable the plugin cache -- this single setting prevents the worst of the disk bloat
  2. Use remote state backends -- stops local state file accumulation
  3. Clean inactive projects -- .terraform/ persists even after you stop working on a project
  4. Pin provider versions tightly -- avoids accumulating multiple minor versions
  5. Set up CI/CD for applies -- reduces the need for local terraform init in every environment
  6. Monitor with ClearDisk -- catch IaC cache growth before it becomes a problem

Terraform Cache vs Other Developer Tools

Developer ToolTypical Cache Size on macOS
Xcode + DerivedData + Simulators15-50 GB
Docker Desktop10-30 GB
Flutter + Dart (everything)10-30 GB
Terraform / OpenTofu (all caches)5-20 GB
node_modules (across projects)5-20 GB
Rust (cargo + target/)5-25 GB
Homebrew2-8 GB
Go modules1-5 GB

Quick Reference Commands

# Audit
find ~ -name ".terraform" -type d -exec du -sh {} + 2>/dev/null | sort -rh | head -10
find ~ -name ".terragrunt-cache" -type d -exec du -sh {} + 2>/dev/null | sort -rh | head -10
du -sh ~/.terraform.d/

# Clean (safe operations)
find ~/Projects -name ".terraform" -type d -mtime +30 -exec rm -rf {} +
find ~/Projects -name ".terragrunt-cache" -type d -exec rm -rf {} +

# Prevent (add to ~/.terraformrc)
# plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

# Re-initialize after cleanup
terraform init
# or: tofu init

Monitor All Your IaC Caches Automatically

Stop guessing which Terraform directories are eating your disk. ClearDisk shows you Terraform, Terragrunt, and every other developer cache in a single menu bar click.

Get ClearDisk -- Free & Open Source