The title of Jonathan Spooner's "Reclaim 100+ GB from Xcode" is the sentence every iOS dev eventually thinks: "The Cleanup Script I Wish I'd Written Years Ago." Most of us only learn about the ~/Library/Developer/Xcode/iOS DeviceSupport/ folder after Xcode refuses to install a debug build, or after macOS pops a low-disk warning mid-archive. By then the folder is usually carrying 20 to 80 GB of per-device debug symbols Xcode quietly downloaded the first time you plugged in a real iPhone running a new iOS version. Xcode never cleans it.
What is the iOS DeviceSupport folder?
The iOS DeviceSupport folder is Xcode's local cache of debug symbols for every iOS version a real device on your Mac has booted into. When you connect an iPhone running, say, iOS 17.5 for the first time, Xcode talks to the device, asks for its dyld shared cache and symbol files, and copies a per-architecture symbol set into a new subfolder. That cache lets the debugger map backtraces back to symbol names, lets LLDB resolve types in Apple frameworks, and lets Instruments show readable call stacks.
Without these symbols you can still run an app, but you cannot debug it properly. With them, Xcode rarely needs to ask the device again. The downside is the per-version cache is sticky. There is no LRU eviction, no quota, no "stale after N months" pass.
Where does the iOS DeviceSupport folder live on a Mac?
One canonical path holds it, and a few sibling paths hold the same thing for other Apple platforms.
~/Library/Developer/Xcode/iOS DeviceSupport/
~/Library/Developer/Xcode/watchOS DeviceSupport/
~/Library/Developer/Xcode/tvOS DeviceSupport/
~/Library/Developer/Xcode/visionOS DeviceSupport/
Inside iOS DeviceSupport/, every subfolder is named with the OS version, build number, and CPU architecture of a device Xcode has seen. A typical iOS dev Mac after a year looks like this:
ls ~/Library/Developer/Xcode/iOS\ DeviceSupport/
# 15.5 (19F77) arm64e
# 16.0 (20A362)
# 16.4 (20E247) arm64e
# 17.0 (21A329) arm64e
# 17.2 (21C62) arm64e
# 17.4 (21E219) arm64e
# 17.5 (21F79) arm64e
# 18.0 (22A3354) arm64e
# 18.1 (22B83) arm64e
# 18.2 beta 2 (22C5125e) arm64e
Each one of those subfolders is typically 1 to 3 GB of symbol files, plus a copy of the device's dyld shared cache. Stack ten of them and you are already over 20 GB on the iOS DeviceSupport folder alone.
Why does the iOS DeviceSupport folder get so large?
Three behaviors compound:
- Xcode writes a new entry on every new OS version, including beta point releases. A device on iOS 18.0, then 18.1 beta 2, then 18.1 GM, then 18.2 RC produces four entries from the same phone.
- Team devices on different patch versions each create their own entry. A team of five on mixed iPhones across iOS 17.4, 17.5, 18.0, and 18.1 generates at least four distinct DeviceSupport folders.
- Xcode never deletes anything here. Uninstalling Xcode usually leaves
~/Library/Developer/Xcode/largely intact because the installer treats that path as user data.
The result is monotonic growth. After two years of iOS work, 30 to 60 GB in this one folder is routine. Heavy beta testers and contractors juggling client devices regularly hit 80 GB. None of it shows up in Xcode's storage UI, and none of it triggers a warning.
How do I measure my iOS DeviceSupport folder size?
Two commands. The first sizes the whole folder, the second breaks it down per OS version so you can decide what to drop.
# Total size of every Apple-platform DeviceSupport folder.
du -sh ~/Library/Developer/Xcode/*DeviceSupport 2>/dev/null
# iOS DeviceSupport, one line per version, biggest at the bottom.
du -sh ~/Library/Developer/Xcode/iOS\ DeviceSupport/*/ 2>/dev/null | sort -h
# How many distinct iOS versions are cached.
ls -1 ~/Library/Developer/Xcode/iOS\ DeviceSupport/ | wc -l
A clean dev Mac has 3 to 5 entries summing to 5 GB or less. North of 15 versions or 25 GB is a cleanup target. North of 50 GB across the four siblings is a high-confidence cleanup you can run today.
Is it safe to delete the iOS DeviceSupport folder?
Yes, with a clear cost. Three classes of entries live under the path:
| Class | Example | Safe to delete? | What you lose |
|---|---|---|---|
| Old major versions below deployment target | iOS 14 entry on an app shipping iOS 16+ | Yes, very safe | Nothing, you do not build for it |
| Beta point releases superseded by GM | 18.2 beta 2 once 18.2 shipped |
Yes, safe | A first-debug delay only if a device still runs the beta |
| Current major version you actively debug | 18.1 (22B83) on your daily phone |
Yes, with cost | A few-minute first reconnect to redownload symbols |
No class causes permanent damage, because every subfolder is content Xcode can refetch from a connected device. The trade is time: first debug per version takes longer after a delete.
One rule: quit Xcode first. Xcode holds file handles on symbol files during a debug session, and moving them mid-session can wedge the debugger.
How do I clean the iOS DeviceSupport folder step by step?
Six steps, none destructive without a Trash safety net:
# Step 1. Quit Xcode and the Simulator so nothing holds file handles.
osascript -e 'quit app "Xcode"' 2>/dev/null
osascript -e 'quit app "Simulator"' 2>/dev/null
sleep 2
# Step 2. Audit. Sort every iOS DeviceSupport version by size.
du -sh ~/Library/Developer/Xcode/iOS\ DeviceSupport/*/ 2>/dev/null | sort -h
# Step 3. Move every entry below your deployment target to Trash.
# Replace the version you no longer build for.
mv ~/Library/Developer/Xcode/iOS\ DeviceSupport/14.* \
~/.Trash/ 2>/dev/null
mv ~/Library/Developer/Xcode/iOS\ DeviceSupport/15.* \
~/.Trash/ 2>/dev/null
# Step 4. Move stale beta entries that have a shipped successor.
mv ~/Library/Developer/Xcode/iOS\ DeviceSupport/*beta* \
~/.Trash/ 2>/dev/null
# Step 5. Do the same sweep for watchOS, tvOS, visionOS.
du -sh ~/Library/Developer/Xcode/watchOS\ DeviceSupport/*/ 2>/dev/null | sort -h
du -sh ~/Library/Developer/Xcode/tvOS\ DeviceSupport/*/ 2>/dev/null | sort -h
# Step 6. Confirm what is left, then reopen Xcode.
du -sh ~/Library/Developer/Xcode/*DeviceSupport 2>/dev/null
open -a Xcode
Steps 3 and 4 reclaim almost all the disk. For a heavier sweep, drop every entry for an iOS version you no longer have a device on. If you are wrong, Xcode redownloads on next connect.
mv ... ~/.Trash/ beats rm -rf for the reason the brtkwr "Using Claude to free 200GB" writeup makes explicit: "After the initial Docker/cache cleanup freed 150GB, going back and asking 'what else?' found another 75GB." The second pass only works because the first left a recovery path. Nuke the wrong version with rm -rf and the symbols still come back from a device, but you lose the option to drag the folder out of Trash if Xcode behaves oddly mid-session.
How does iOS DeviceSupport compare to other Xcode cache folders?
The DeviceSupport folder is one of five places Xcode quietly stores big binary data on your Mac. They behave differently and deserve different treatment.
| Folder | What it stores | Safe to delete? | Auto-regenerates? |
|---|---|---|---|
iOS DeviceSupport/ |
Per-version debug symbols from real devices | Yes | Yes, on next device connect |
DerivedData/ |
Per-project build cache | Yes | Yes, on next build |
Archives/ |
Shipped .xcarchive bundles with dSYMs |
Yes, with caveats | No, archives are not rebuilt |
CoreSimulator/Devices/ |
Per-simulator filesystem and app state | Yes, per device | Yes, on next simulator boot |
CoreSimulator/Caches/dyld/ |
Per-runtime cached dyld shared caches | Yes | Yes, on next simulator boot |
The big tell: anything Xcode regenerates on demand is a strong cleanup candidate. Anything Xcode does not rebuild (the Archives folder is the main one) needs more care. iOS DeviceSupport sits firmly in the "Xcode rebuilds it" column. For deeper coverage of the other rows, see How do I safely delete Xcode DerivedData? and How do I reclaim disk from Xcode simulators?.
How do I stop iOS DeviceSupport from growing again?
You cannot stop Xcode from writing new entries. Every new iOS version on every device is a fresh symbol download by design, because the debugger needs them. What you can do is cap accumulation with a quarterly sweep tied to milestones you already track:
- Every time you bump your app's minimum deployment target. Drop every entry below the new target the same day.
- Every time Apple ships a major iOS GM. Drop every beta entry for that major version once a device is on the GM.
- Every quarterly tooling rotation. Audit DeviceSupport alongside DerivedData and Archives, and trim anything older than the last two majors plus current.
For automation, a small launchd job is enough:
# ~/Library/LaunchAgents/com.cleanmydev.ios-devicesupport.plist
# Runs the first of every month at 09:00 local time.
# Drops any iOS DeviceSupport entry not touched in 120 days.
find ~/Library/Developer/Xcode/iOS\ DeviceSupport \
-mindepth 1 -maxdepth 1 -type d \
-atime +120 \
-exec mv {} ~/.Trash/ \;
That single line keeps the folder bounded. If a device on an "expired" iOS version reconnects, Xcode just rebuilds the entry. No interactive prompt, no risk of a developer forgetting the sweep.
Why use CleanMyDev for iOS DeviceSupport cleanup?
You do not need an app to run du and mv against one folder. You do need one the moment you have 22 DeviceSupport entries across iOS, watchOS, tvOS, and visionOS, half on beta point releases, and a hand-rolled find command is one typo away from clobbering the wrong subtree. CleanMyDev sizes every entry under all four DeviceSupport siblings, labels each by OS version, build, and last access date, and flags any below your project's deployment target. Every deletion is a Move to Trash, restorable for 30 days. No rm -rf, no sudo, no scareware modal.
It also covers DerivedData, Archives, CoreSimulator devices, AssetsV2 runtimes, and the Swift Package Manager cache in the same pass. CleanMyDev is $9.99 once, with every Xcode path preconfigured.