how to

Why is my Mac disk full? A visual investigation using a disk treemap

the short answer

A Mac disk fills up faster than expected because of five compounding culprits that the standard storage view doesn't show clearly: Xcode's DerivedData and simulator runtimes (30 GB+), accumulated node_modules directories in old project folders, Docker image layers, a Photos library that grows silently, and a downloads folder used as permanent storage — a disk treemap like grove surfaces all five in under a minute so you know exactly what to target.

the 'disk almost full' notification appears, you open about this mac, and the storage bar is mostly 'documents' and 'system data' with no way to drill in. you uninstall a couple of apps you rarely use, free up 3 gb, and a week later the warning is back. the apps weren't the problem.

culprit 1: xcode's derived data and simulator runtimes

if you do any ios or macos development, xcode is almost certainly the top consumer on your disk. ~/library/developer/xcode/deriveddata holds build artefacts from every project you've ever compiled — and it accumulates across projects, never clearing itself. a machine with a few years of active development can have 20–40 gb in deriveddata alone, most of it from projects you finished long ago.

xcode simulator runtimes are a separate problem: each ios, watchos, and tvos version you've tested against adds a 2–8 gb runtime to ~/library/developer/coresimulator/profiles. twelve ios versions over three years of active development adds up fast. clear both via xcode → settings → platforms → delete simulator runtimes you no longer need, and clear deriveddata manually or via product → clean build folder.

culprit 2: node_modules in old project directories

node_modules is the most notorious space consumer in the javascript ecosystem. each project's node_modules can run to 300 mb–1 gb depending on the dependency tree, and the directories stay on disk forever unless you manually remove them. a developer who's cloned thirty projects over three years might have 20 gb of node_modules from projects they haven't touched in months.

grove's treemap surfaces these immediately: you'll see a cluster of large directories under your projects folder, each named node_modules. if the parent project hasn't been opened in six months and you have a lockfile to reinstall from, the node_modules is safe to delete.

culprit 3: docker images and volumes

docker stores all its image layers, containers, and volumes in a single virtual disk image at ~/library/containers/com.docker.docker/data (on mac desktop) or in /var/lib/docker on linux. this file grows as you pull images and never shrinks automatically, even when you remove containers.

the fastest remedy: `docker system prune -a --volumes` removes all unused images, stopped containers, and dangling volumes. if you're not actively using docker, removing docker desktop entirely recovers the full allocation. grove shows you the actual size of the docker disk image in its treemap — often 15–30 gb for an active development machine.

culprit 4: photos library

if your iphone photos sync to your mac (even with icloud photos set to 'optimise storage'), the photos library grows continuously. by default it lives at ~/pictures/photos library.photoslibrary and expands with every photo, video, and live photo you've taken. 4k video footage from an iphone adds up very quickly.

grove shows the photos library as a single large block — often 40–150 gb on a machine used for a few years of iphone photography. moving the library to an external drive is the cleanest solution; setting icloud photos to 'optimise mac storage' in system settings reduces the on-disk copy to previews.

culprit 5: the downloads folder used as permanent storage

downloads is a category everyone knows about but underestimates. installer disk images (.dmg files), zip archives, pdf downloads, and large media files accumulate over years of use. many people download a file once, use it, and never think about it again — but the file stays in downloads indefinitely.

a quick grove drill-in to ~/downloads usually finds a mixture of dmgs from apps already installed, zip archives of projects already extracted, and media files already consumed. the disk image files (.dmg) are almost always safe to delete after you've installed the app — the app lives in /applications, not in the installer.

how it works

  1. 01

    open grove and scan

    click scan to walk your disk. the treemap renders in under a minute for a 512 gb ssd.

  2. 02

    identify the largest blocks

    the biggest rectangles are your biggest consumers. hover to confirm the path, then click to drill in.

  3. 03

    check each culprit

    look for ~/library/developer (xcode), project folders with node_modules, ~/library/containers/com.docker.docker, ~/pictures, and ~/downloads. each shows up clearly in the treemap.

  4. 04

    reveal in finder, then decide

    click 'reveal in finder' on any block to open it directly. inspect before you delete — then remove what you don't need from finder.

frequently asked

why does the mac show less free space than i expect after deleting files?

two likely reasons: the files you deleted are still in the trash (empty the trash to reclaim the space), or the freed space was partially replaced by new local time machine snapshots that macos created automatically. run `tmutil deletelocalsnapshots /` in terminal if you want to also clear those.

is it safe to delete the xcode deriveddata folder?

yes, entirely safe. deriveddata is a build cache — xcode rebuilds it the next time you compile a project. the only cost is a slightly longer build the first time. you can clear it via product → clean build folder in xcode, or by deleting ~/library/developer/xcode/deriveddata in finder.

how do i find all my node_modules folders at once?

in terminal: `find ~ -name node_modules -prune -maxdepth 8 -print 2>/dev/null | head -50`. this finds node_modules directories up to 8 levels deep in your home folder. grove's treemap shows the same thing visually — a cluster of same-sized blocks wherever you have javascript projects.

will deleting docker images affect my running containers?

`docker system prune -a` removes images that aren't attached to a running or stopped container. running containers are safe. stopped containers are removed — run `docker ps -a` first to check what's stopped and whether you need it. if you want to be selective, `docker image ls` shows all images; `docker rmi <image-id>` removes specific ones.

Last updated June 22, 2026

ready to try grove?

download grove