Skip to content

Instantly share code, notes, and snippets.

@dytra
Last active September 8, 2026 02:04
Show Gist options
  • Select an option

  • Save dytra/d101dbef9d711fab982a2c62b76aca4f to your computer and use it in GitHub Desktop.

Select an option

Save dytra/d101dbef9d711fab982a2c62b76aca4f to your computer and use it in GitHub Desktop.
a CLI utility that analyzes system disk usage taken up by Xcode and iOS Simulators, listing every individual simulator sorted by disk size (with UUID, name, and status), and provides commands/flags to clean build caches (DerivedData) or erase simulator data to reclaim disk space.
#!/usr/bin/env bash
# ==============================================================================
# iOS Simulator & Xcode Disk Usage Inspector
# Usage: ./scripts/ios_disk_usage.sh [--erase <UUID_or_Name>] [--erase-all] [--clean-deriveddata] [--delete-unavailable]
# ==============================================================================
set -euo pipefail
BOLD='\033[1m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
echo -e "${BOLD}${CYAN}======================================================${NC}"
echo -e "${BOLD}${CYAN} iOS Simulator & Xcode Disk Usage Report ${NC}"
echo -e "${BOLD}${CYAN}======================================================${NC}\n"
# 1. System Available Disk Space
AVAIL_DISK=$(df -h / | awk 'NR==2 {print $4}')
TOTAL_DISK=$(df -h / | awk 'NR==2 {print $2}')
echo -e "${BOLD}System Disk (/):${NC} ${GREEN}${AVAIL_DISK}${NC} available out of ${TOTAL_DISK}\n"
# 2. Overall Directory Breakdown
CORE_SIM_PATH="$HOME/Library/Developer/CoreSimulator"
DERIVED_DATA_PATH="$HOME/Library/Developer/Xcode/DerivedData"
if [ -d "$CORE_SIM_PATH" ]; then
CORE_SIM_SIZE=$(du -sh "$CORE_SIM_PATH" 2>/dev/null | awk '{print $1}')
else
CORE_SIM_SIZE="0B"
fi
if [ -d "$DERIVED_DATA_PATH" ]; then
DERIVED_DATA_SIZE=$(du -sh "$DERIVED_DATA_PATH" 2>/dev/null | awk '{print $1}')
else
DERIVED_DATA_SIZE="0B"
fi
echo -e "${BOLD}Developer Cache Summary:${NC}"
echo -e " • CoreSimulator Total: ${YELLOW}${CORE_SIM_SIZE}${NC}"
echo -e " • Xcode DerivedData: ${YELLOW}${DERIVED_DATA_SIZE}${NC}\n"
# 3. Per-Simulator Breakdown
DEVICES_DIR="$HOME/Library/Developer/CoreSimulator/Devices"
if [ ! -d "$DEVICES_DIR" ]; then
echo -e "${RED}No CoreSimulator Devices directory found at $DEVICES_DIR${NC}"
exit 0
fi
echo -e "${BOLD}Per-Simulator Disk Usage:${NC}"
printf "%-10s | %-28s | %-10s | %-36s\n" "SIZE" "DEVICE NAME" "STATUS" "UUID"
echo "---------------------------------------------------------------------------------------"
temp_file=$(mktemp)
for d in "$DEVICES_DIR"/*; do
if [ -f "$d/device.plist" ]; then
uuid=$(basename "$d")
name=$(plutil -extract name xml1 -o - "$d/device.plist" 2>/dev/null | sed -n 's/.*<string>\(.*\)<\/string>.*/\1/p')
runtime=$(plutil -extract runtime xml1 -o - "$d/device.plist" 2>/dev/null | sed -n 's/.*<string>\(.*\)<\/string>.*/\1/p' | sed 's/com.apple.CoreSimulator.SimRuntime.//' | tr '-' '.')
# Check if booted
status="Shutdown"
if xcrun simctl list devices | grep -q "$uuid.*Booted"; then
status="Booted"
fi
# Raw bytes for sorting
raw_bytes=$(du -sk "$d" 2>/dev/null | awk '{print $1}')
human_size=$(du -sh "$d" 2>/dev/null | awk '{print $1}')
echo "$raw_bytes|$human_size|$name ($runtime)|$status|$uuid" >> "$temp_file"
fi
done
if [ -s "$temp_file" ]; then
sort -t'|' -k1 -nr "$temp_file" | while IFS='|' read -r raw human name status uuid; do
if [ "$status" = "Booted" ]; then
formatted_status="${GREEN}${status}${NC}"
else
formatted_status="${NC}${status}${NC}"
fi
printf "%-10s | %-28s | %-10b | %-36s\n" "$human" "${name:0:28}" "$formatted_status" "$uuid"
done
else
echo "No active simulators found."
fi
rm -f "$temp_file"
echo -e "\n${BOLD}${CYAN}======================================================${NC}"
echo -e "${BOLD}Cleanup Options Available:${NC}"
echo -e " 1. Erase a specific simulator (e.g., iPhone 16e):"
echo -e " ${GREEN}./scripts/ios_disk_usage.sh --erase \"iPhone 16e\"${NC}"
echo -e " ${GREEN}xcrun simctl erase <UUID>${NC}"
echo -e " 2. Erase all simulator app caches (reclaims ~8-10 GB):"
echo -e " ${GREEN}xcrun simctl erase all${NC}"
echo -e " 3. Clear Xcode build cache (reclaims DerivedData):"
echo -e " ${GREEN}rm -rf ~/Library/Developer/Xcode/DerivedData/*${NC}"
echo -e " 4. Delete obsolete/unavailable simulators:"
echo -e " ${GREEN}xcrun simctl delete unavailable${NC}"
echo -e "${BOLD}${CYAN}======================================================${NC}"
# Handle Optional Flags
while [[ $# -gt 0 ]]; do
case "$1" in
--erase)
target="${2:-}"
if [ -z "$target" ]; then
echo -e "${RED}Error: --erase requires a device name or UUID (e.g., 'iPhone 16e')${NC}"
exit 1
fi
echo -e "\n${YELLOW}Shutting down & erasing data for '$target'...${NC}"
xcrun simctl shutdown "$target" 2>/dev/null || true
xcrun simctl erase "$target"
echo -e "${GREEN}Successfully erased data for '$target'.${NC}"
shift 2
;;
--erase-all)
echo -e "\n${YELLOW}Running: xcrun simctl erase all...${NC}"
xcrun simctl erase all
echo -e "${GREEN}Successfully erased all simulator data.${NC}"
shift
;;
--clean-deriveddata)
echo -e "\n${YELLOW}Clearing Xcode DerivedData...${NC}"
rm -rf "$HOME/Library/Developer/Xcode/DerivedData"/*
echo -e "${GREEN}Successfully cleared DerivedData.${NC}"
shift
;;
--delete-unavailable)
echo -e "\n${YELLOW}Deleting unavailable simulators...${NC}"
xcrun simctl delete unavailable
echo -e "${GREEN}Successfully deleted unavailable simulators.${NC}"
shift
;;
*)
shift
;;
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment