How to Clean Xcode Cache and Derived Data
Xcode is the reason your Mac is full.
Not your photos, not your Downloads folder. Xcode, and the four directories it fills without ever mentioning it.
Here is what is actually in them, measured on the Mac I am writing this on, and what each one costs to delete. Some of it is free to remove. One of it is expensive in a way that is not obvious. And the number your disk analyzer shows you for the biggest one is probably wrong, in a direction that will disappoint you.
What Xcode is holding, measured
Real numbers from this machine (macOS 26.5, Xcode 26.6, APFS):
| Directory | Size here | What it is | Cost to delete |
|---|---|---|---|
~/Library/Developer/XCTestDevices | 31 GB | Simulator clones from parallel testing | Nothing. This is orphaned |
~/Library/Developer/CoreSimulator | 25 GB | Your simulator devices and their data | Loses app installs and simulator state |
~/Library/Developer/Xcode/DerivedData | 13 GB | Build products, module cache, search index | One slow rebuild and re-index per project |
/Library/Developer/CoreSimulator/Volumes | 16 GB | Downloaded simulator runtimes | A multi-gigabyte re-download from Apple |
~/Library/Caches/com.apple.dt.Xcode | 1.4 MB | Xcode’s own app cache | Nothing |
Two directories that most guides list did not exist on this machine at all: ~/Library/Developer/Xcode/Archives and ~/Library/Developer/Xcode/iOS DeviceSupport. Check before you plan around them.
Check yours:
du -sh ~/Library/Developer/Xcode/DerivedData \
~/Library/Developer/CoreSimulator \
~/Library/Developer/XCTestDevices \
~/Library/Caches/com.apple.dt.Xcode
Start with the free win: orphaned test clones
XCTestDevices was the largest single directory here, at 31 GB across 13 simulator bundles. Every one of them was named some variant of “Clone 2 of iPhone 17 Pro”.
These come from parallel testing. When you run tests with parallelization enabled, Xcode clones your simulator once per test worker, runs the tests across them, and is supposed to clean up afterward. It keeps them so the next run starts faster, and it abandons them entirely when a run crashes, times out, or you hit Stop.
The result accumulates silently. The 13 clones here had modification times spread across a full week, meaning they survived many sessions without anything reaping them.
The catch that makes them easy to miss: XCTestDevices is a separate simulator device set. The usual cleanup command ignores it completely. You need --set:
# The usual cleanup, which does NOT touch XCTestDevices
xcrun simctl delete unavailable
# The one that does
xcrun simctl --set ~/Library/Developer/XCTestDevices delete all
List them first if you want to see what you are about to remove:
xcrun simctl --set ~/Library/Developer/XCTestDevices list devices
Nothing you lose here matters. Xcode recreates a clone the next time it needs one.
DerivedData: safe, but not free
DerivedData holds build products, the precompiled module cache, and the search index for every project you have opened. Nine project folders here, plus CompilationCache.noindex, ModuleCache.noindex, SDKStatCaches.noindex, and SymbolCache.noindex.
Everything in it is generated. Delete it and Xcode rebuilds all of it.
That last sentence is the whole trade. On a small project you lose thirty seconds. On a large one you lose a full clean build plus re-indexing, which on a big Swift codebase can mean five to fifteen minutes before autocomplete works again.
Delete the whole thing:
rm -rf ~/Library/Developer/Xcode/DerivedData
Or one project, which is usually what you actually want when you are chasing a stale-build bug:
rm -rf ~/Library/Developer/Xcode/DerivedData/YourProject-*
Xcode’s own Product menu has “Clean Build Folder” (Shift-Command-K), which clears the current scheme’s build products without nuking the index. Try that first when you are debugging, and save the full delete for when you actually need the disk space.
Simulator runtimes: the expensive one
/Library/Developer/CoreSimulator/Volumes holds downloaded OS runtimes. One runtime here (iOS 26.5) at 16 GB.
This is the one directory where “you can always get it back” is technically true and practically painful. Runtimes are not rebuilt locally, they are re-downloaded from Apple. Deleting a 16 GB runtime to free space means a 16 GB download the next time you need to test against that OS version, on Apple’s servers, at whatever speed they feel like that day.
See what you have:
xcrun simctl list runtimes
If you are holding runtimes for iOS versions you no longer support, delete them. If it is the runtime you test against daily, leave it and find your space elsewhere.
The part where your disk analyzer lies to you
Here is the thing that makes Xcode cleanup genuinely confusing, and it is not Xcode’s fault.
APFS supports cloned files. Apple’s own clonefile(2) manual page describes it directly: the cloned file “shares its data blocks with the src file” and writes to either copy are private to the file being written. Copying a file this way costs almost no disk space.
Simulator clones are exactly this. Those 13 bundles in XCTestDevices at 2.2 to 2.6 GB each are not 13 independent copies of a simulator. They share most of their blocks with the original.
But du walks the directory tree and adds up file sizes. It counts shared blocks once per clone. So does Finder’s Get Info. So does every disk analyzer that works the same way.
The consequence is blunt: 31 GB is a ceiling, not a promise. As Adam Leventhal put it in his APFS analysis, block sharing means that just as copying a file may take up no space, deleting a file may free no space.
I have been burned by this specifically. On an earlier cleanup on this machine, du reported 76 GB of orphaned simulator clones. After deleting all of them, df showed roughly 1 GB actually recovered, and most of the space that did come back that day came from an unrelated npm cache clear I happened to run in the same session. The clones were sharing nearly all their blocks with the original simulator.
How to actually measure it
Do not trust one tool. Measure free space before and after:
# Before
df -h /System/Volumes/Data
# Delete one group, and only one
xcrun simctl --set ~/Library/Developer/XCTestDevices delete all
# After. Wait ~20 seconds first; APFS frees space asynchronously
df -h /System/Volumes/Data
Two rules that fall out of this:
- Delete one group at a time and measure between each. If you clear DerivedData, simulator clones, and npm caches in one go, you learn nothing about which one helped, and next time you will delete the expensive one for no reason.
- Measure the Data volume, not
/. On current macOS the system volume is sealed and read-only. It reports about 16 GB used here regardless of what you do.df -h /will make it look like nothing changed.
What to delete, in order
Working from best to worst return on effort:
- Orphaned test clones (
xcrun simctl --set ~/Library/Developer/XCTestDevices delete all). Pure garbage, no downside, though see the caveat above about how much you actually get back. - Unavailable simulators (
xcrun simctl delete unavailable). Devices tied to SDKs your current Xcode no longer supports. - DerivedData for projects you are not actively working on. Costs a rebuild you were not going to do today anyway.
- Simulator runtimes for OS versions you no longer support. Real space, real download cost.
- DerivedData entirely. Only when you need the space now and accept a slow morning.
What not to bother with
~/Library/Caches/com.apple.dt.Xcodewas 1.4 MB here. Guides list it because it sounds important. It is not where your disk went.- Deleting Xcode itself and reinstalling. This is advice from a decade ago and it does not touch most of the directories above, because they live in your home folder and survive the reinstall.
- Third-party “developer cleaner” apps that promise to reclaim the
dunumber. They cannot beat physics on shared blocks, and the number they show you before you buy is the same inflated ceiling.
Keeping it from coming back
None of this stays fixed. Parallel testing keeps orphaning clones, DerivedData refills as you build, and you will download another runtime the next time Apple ships a beta.
Two habits that work:
- Run the
du -shcommand above once a month. It takes five seconds and tells you which directory grew. - Put the cleanup commands in a shell alias so it is one word instead of four paths you have to remember.
If you would rather see it than remember to check it, Storage Peek keeps disk usage in your menu bar and can alert you at a threshold you set, which turns “my Mac is full during a build” into something you saw coming. It is $2.99, one time.
Worth being straight about one thing, given everything above: Storage Peek walks the filesystem the same way du does, so it inherits the same APFS blind spot. It will show you the same inflated number for cloned simulator directories. No treemap-style analyzer can tell you what deleting will actually free, which is exactly why the df before-and-after check matters.
FAQ
Is it safe to delete DerivedData?
Yes. Everything in it is generated from your source. The only cost is time: a clean rebuild plus re-indexing.
Will deleting DerivedData fix my weird build error?
Often, yes. Stale module caches cause a specific flavor of nonsense error where the code is obviously correct and the compiler disagrees. Try Shift-Command-K first, then delete the project’s DerivedData folder, then delete the whole directory.
Why does xcrun simctl delete unavailable not free much space?
Because it only touches the default device set. Your parallel-testing clones live in XCTestDevices, which needs the --set flag. That is the single most commonly missed step.
Why did I free 40 GB according to my disk analyzer but only 2 GB according to Finder?
APFS block sharing. The analyzer counted shared blocks once per clone; the space was never separately allocated, so deleting it never returned it. df is the honest number.
Can I stop Xcode from creating clones in the first place?
You can disable parallel testing per scheme, but you would be trading test speed for disk space, which is usually the wrong trade. Cleaning up periodically is the better habit.
Do I need to quit Xcode first?
For DerivedData, yes, or Xcode may recreate parts of it while you are deleting. For simulator cleanup, quit the Simulator app.
The short version
Check all four directories with one du -sh. Clear orphaned test clones with the --set flag, since the normal command skips them. Treat DerivedData as free to delete and simulator runtimes as expensive. Then measure with df -h /System/Volumes/Data before and after, because on APFS the size your analyzer shows is a ceiling, not what you are getting back.