df reports 387 GiB used on my data volume, 50 GiB free, 89 percent full. When I
saw that number I did what everybody does: I started hunting for large files.
What I found wasn't a large file. My home folder was still holding the
belongings of apps that no longer exist on this machine.
It isn't that I didn't know a deleted app leaves traces behind — the entire
business model of apps sold as "cleaners" rests on it. What I didn't know was
how concrete the traces are. The cookie databases of a Postman that is no
longer installed are sitting there, last written a year ago. The 252 MiB profile
folder of a browser that is also gone is sitting there. A preferences file that nothing has touched for five
hundred and seventy-eight days is sitting there.
This piece is the story of that count: what I found, the three times I got the
count wrong, and why Apple describes this behaviour not as a defect but as a
documented choice.
An archive that fell out of a full disk
Let me give the result first, because everything else is about how that number
was built.
Every measurement here was taken on the afternoon of 12 October 2026, on a
single Mac running macOS 26.6.2 (build 25G83). The numbers belong to this
machine; yours will differ.
The measurement has two stages, because there are two separate questions: "whose
is this?" and "how much room does it take?"
Stage one — find the candidates. Five locations in my home folder have names
that are bundle identifiers: under ~/Library, Containers, Preferences,
HTTPStorages, WebKit and Saved Application State. 1,430 entries in total.
Only those five, because you can only safely look for an owner in an entry whose
name is an identifier. I compared them against a full list of the application
bundles that genuinely exist on this machine, and verified the non-matches with
a second method. What survived was 18 products: no package anywhere on disk.
Stage two — measure the footprint of those 18. Once the owner is confirmed
gone, name matching is no longer needed; I swept eleven directories under
~/Library by product name — Application Support (where nearly all of the
bytes are), Containers, Caches, Preferences, HTTPStorages, WebKit,
Logs, Saved Application State, Application Scripts, Group Containers and
Application Support/CrashReporter. Those 18 products hold 79 leftovers and
661.25 MiB (693,374,976 bytes).
Skip that distinction and the numbers won't add up: inside the five locations,
everything left by Atlas and Postman amounts to a few hundred KiB of plists and
cookie files. Nearly all of the 661 MiB comes from Application Support, which
stage one never looked at.
Six hundred sixty-one MiB is 0.17 percent of a 387 GiB footprint. So this is not
a space problem; let me say up front that the piece won't end with "clean your
disk." What stopped me wasn't the size, it was the contents.
The three wrong answers
The count said 560, then 77, then 93, then 18. I believe the fourth. That chain
is the most instructive part of this — because every intermediate number sounded
perfectly reasonable at the time.
Wrong answer one: my inventory was incomplete. There are 773
directories under ~/Library/Containers; three are named with a UUID and the
remaining 770 are shaped like bundle identifiers. I compared those names against
the 748 identifiers I had collected from the .app bundles in /Applications
and ~/Applications. 560 didn't match. I had a reassuring moment — "so I was
right" — and then I looked at the list. Every one of the first twenty lines
started with com.apple.: com.apple.DiagnosticExtensions.WiFi,
com.apple.PDFKit.PDFImporter, com.apple.inputmethod.TCIM. Those aren't
deleted apps; they are the system's own extensions and services. They live
inside frameworks and never appear as .app bundles. The fault was in my inventory, not on the disk.
So the inventory got fixed: eleven bundle types under nine roots
(/System/Library, /System/Applications, /System/iOSSupport, /Library,
/Applications, ~/Library, ~/Applications, /usr/libexec, /usr/share) —
the full command is below — 23,217 bundle directories, 8,967 readable
Info.plist files, 6,836 distinct identifiers. On
top of that I added LaunchServices' own registry (lsregister -dump). The
orphan count fell from 560 to 77.
Wrong answer two: I treated every directory name as an identifier. When I
widened the scan to Group Containers, nearly every directory came back as
"owner missing." The line at the top of the list put me back in my place:
group.net.whatsapp.WhatsApp.shared, 7.5 GiB. WhatsApp is installed on this
machine and I open it every day. My test was nonsense, because the name of an
app-group directory is not an application identifier — it's a separate
namespace. Apple's documentation says so plainly: on macOS the group directory
lives under ~/Library/Group Containers/<application-group-id>, and that
identifier begins with the developer's team identifier. So it will never match a
.app identifier.
That's why Group Containers and Application Scripts are out of the
candidate-finding stage: in those two locations, whether an entry is an
orphan can only be settled by reading the entitlements of installed apps, which
is outside this piece's scope. But in stage two, looking there by the name of a
product already proven gone is safe — all three of Transmit's leftovers sit in
those two locations. Hunting for orphans is one job; counting the belongings of
a known orphan is another.
That gave me a general lesson too: a measurement method is not usable until
you have tested it against a deliberate false positive. WhatsApp's 7.5 GiB
refuted that test single-handedly. The same thing happened when I asked how much
free space the disk had using five different methods —
five answers, 13.5 GiB apart.
Wrong answer three: I mistook a preference domain for an app. Reading the
remaining 93 candidates one by one, among them were
com.firebase.FIRInstallations, com.segment.storage.oai,
org.cups.PrintingPrefs and com.qtproject. Those aren't deleted apps; they
are preference domains that libraries inside installed apps open in their own
name. The same list also held com.microsoft.teams2.agent — Teams is installed
— and com.parallels.desktop.appstore.prlctl — Parallels Desktop is installed.
Helper components open containers on behalf of apps whose owner is very much
alive.
Let me also explain why the chain rises from 77 to 93, because otherwise it
looks odd: 77 was the orphan count for Containers alone; 93 was the orphan
count across all five locations. The third step threw out the wrong locations
and added the right ones at the same time.
The fourth and final filter was this: for every candidate I asked Spotlight
(mdfind "kMDItemCFBundleIdentifier == '...'") and also searched the disk by
the product's name. I counted an identifier as a leftover only if that
product's application bundle was nowhere to be found. Eighteen products passed.
Eighteen apps, seventy-nine traces
In the table, "last written" is the date of the most recently touched file
belonging to that product; "days" is the time elapsed to today (12 October 2026).
| Product | Traces | Size | Last written | Days |
|---|---|---|---|---|
| ChatGPT Atlas | 8 | 283.12 MiB | 2026-04-13 | 182 |
| Postman | 7 | 188.29 MiB | 2025-10-07 | 370 |
| Foxit PDF Reader | 6 | 115.32 MiB | 2025-06-20 | 479 |
| iMobie AnyUnlock | 8 | 34.63 MiB | 2025-10-28 | 349 |
| CrossOver | 2 | 22.57 MiB | 2026-06-17 | 117 |
| FTP Rush | 2 | 13.83 MiB | 2026-03-16 | 210 |
| Beekeeper Studio | 2 | 2.05 MiB | 2025-10-22 | 355 |
| soloforge | 3 | 0.42 MiB | 2026-03-29 | 197 |
| AVG Secure VPN | 14 | 0.37 MiB | 2025-06-27 | 472 |
| Tenorshare ReiBoot | 6 | 0.26 MiB | 2025-10-28 | 349 |
| Steam Link | 2 | 0.12 MiB | 2025-05-07 | 523 |
| iMyFone iBypasser | 4 | 0.12 MiB | 2025-10-28 | 349 |
| iMobie DroidKit | 4 | 0.08 MiB | 2026-07-11 | 93 |
| erpProject | 2 | 0.03 MiB | 2025-04-05 | 555 |
| Minecraft Launcher | 2 | 0.02 MiB | 2025-03-13 | 578 |
| Cyberduck | 2 | 0.01 MiB | 2026-03-16 | 210 |
| FileZilla | 2 | 0.00 MiB | 2025-07-16 | 453 |
| Transmit | 3 | 0.00 MiB | 2025-07-18 | 451 |
| Total | 79 | 661.25 MiB | — | — |
(The total row is computed from bytes; adding up the rounded values in the
column gives 661.24.)
The distribution is striking: the first three rows are 586.7 MiB, which is 88.7
percent of the total. The remaining fifteen products come to 74.5 MiB all
together. The bottom rows are almost symbolic — the only thing left of FileZilla
are a 119-byte preferences file and a 64-byte sandbox script; the two things
left of Cyberduck are a 6,154-byte preferences file and a 69-byte crash report.
Leaving a 69-byte crash report as an app's memento is, it must be said, not
terribly graceful.
Written down for one location, never written for the rest
So far the story reads like "macOS doesn't clean up." Reading the documentation
took it somewhere stranger.
Apple's containerURL(forSecurityApplicationGroupIdentifier:) documentation says
this for macOS: the system creates the group directory automatically the first
time the app needs it and never removes it. A few paragraphs further down
the same page, the iOS section says the exact opposite: on iOS, when all the
apps in a given app group are removed from the device, the system detects that
condition and removes the group directory as well.
I have to be honest here: that sentence covers only Group Containers, and
only sandboxed apps. About Application Support, where nearly all of my 661 MiB
sits, that document says nothing at all. So I can't claim "Apple documented
this." What I can claim is less comfortable — the policy is written down for
exactly one location, and for the other ten there is no policy anywhere. The
directory whose persistence is documented looks almost transparent next to the
ones whose persistence was never discussed.
Even so, that one sentence gives away the mechanism. On iOS there is an event
called "the last app is gone" and the system reacts to it; on macOS there is no
such event. The reason is guessable — on macOS an app is a file, and
moving it to the Trash is a file operation, not a declaration of intent that the
operating system could read as "I don't want this app any more."
Apple's user-facing page says it indirectly too. The "Delete or uninstall apps
on Mac" document recommends using the app's own uninstaller when one exists, and
gives the reason: that is the best way to delete the app and any login items,
extensions, or other data the app may have stored in other locations. When there
is no uninstaller, the recommended step is a single one: drag the app to the
Trash. There isn't a word claiming that step also takes the "other data" —
because it doesn't.
So the system didn't lie to me. I said "deleted" without reading the
documentation.
What's left isn't settings, it's sessions
If I saw the leftovers as 661 MiB of lost space I wouldn't have written this.
Looking at the contents changed things.
187 MiB of Postman's 188 MiB sit in a single folder:
~/Library/Application Support/Postman/Partitions. Postman is an Electron app
and that folder holds its browser partitions. There are 973 files inside, named
exactly what you'd expect from a browser: Cookies, Cookies-journal,
TransportSecurity, Trust Tokens, Local Storage, Network Persistent State.
I found four separate Cookies files, each 20,480 bytes; the newest was last
written on 7 October 2025. So the cookie databases of an app that is no longer
installed are still in place, untouched by anyone for a year. (A timestamp tells
you when the data was last written, not when the app was removed; the disk keeps
no record of the deletion itself.) I didn't look inside
them, and I wouldn't recommend that you do either; for this measurement the
file's name is already enough.
The row with the most leftovers is one of the smallest: AVG Secure VPN, 14
traces for 0.37 MiB, spread across six locations — Application Support,
Containers, Preferences, HTTPStorages, Application Scripts and
Group Containers. A VPN app touching six places on its way out explains, on
its own, why size is the wrong sort order. The third-largest row, Foxit PDF
Reader's 115 MiB, sits in one place: Application Support/Foxit Software,
untouched for sixteen months.
252 MiB of ChatGPT Atlas's 283 MiB is browser-data, next to it a profiles
directory, six project-g-p-... directories and one user-... directory;
2,967 files in total. It isn't hard to guess what 2,967 files left behind by a
browser are.
One thing needs saying plainly, because I don't want to manufacture false
relief: deleting that cookie file does not end the session. A cookie is the
key to a session held on a server; deleting the file throws away your copy while
the session keeps living at the other end. If you actually want it closed, the
thing to do is "sign out of all sessions" in that service's account settings —
disk cleanup complements that, it doesn't replace it.
Second: even once you delete these files, copies can remain. APFS local
snapshots and Time Machine hold the pre-deletion state for a while. "I deleted
it" means the number of copies went down by one.
Add Apple's warning from the UserDefaults documentation to that: the defaults
system stores information on disk in an unencrypted format, which is why
personal or sensitive information shouldn't be stored as settings and belongs in
the Keychain instead. The documentation is telling developers this. The
user-side corollary is: whether you need to worry about what a deleted app put
in its preferences file depends on whether that developer followed the warning.
If you're curious, there's a safe way to look — defaults read <domain> reads
the contents without touching the file. I didn't read any for this piece; names
and dates were enough.
There's a share of this that falls to me as well. The backups of this machine
aren't kept on another machine,
but if they were, every one of these 79 traces would also have gone into the
backups — meaning the copies of what I called "deleted" would be multiplying.
Leftovers never sit alone; they sit inside everything you back up.
Atlas left twice
The largest row in the table deserves its own parenthesis.
ChatGPT Atlas was the browser OpenAI shipped on macOS in October 2025. It is no
longer on this machine; its leftovers were last written on 13 April 2026, so I
hadn't used it after April. OpenAI retired the product this summer; the "ChatGPT Atlas
retirement" page in their help centre states the product no longer receives
updates and tells users this about their data: bookmarks, open tabs and browsing
history do not transfer automatically; sign in to sites again in your new
browser; don't share your cookie or session files with other people.
Here's the interesting part: OpenAI has not missed this gap. The same page's FAQ
warns outright not to assume that uninstalling Atlas, or changing ChatGPT Memory
settings, deletes that data. And the "Remove Atlas from your Mac" heading both
points to Apple's instructions for uninstalling apps and adds: if you still need
data saved in Atlas, contact OpenAI Support before deleting local browser data.
So the vendor is telling me not to believe I've deleted the data. What it
doesn't tell me is where that data lives or how to remove it. It points at
Apple, Apple says "drag it to the Trash if there's no uninstaller," and dragging
to the Trash doesn't take the data. The gap isn't something nobody noticed; it
gets announced and then left open. The upshot is that a 252 MiB browser profile
sits there as a pile of files whose owner has withdrawn from both my disk and
the market, with no software left to come back and ask for it.
Four tools in sixty-two minutes
The unexpected part of the count was this: these files behave like an archive.
I looked at the times on the four leftovers dated 28 October 2025: Tenorshare
ReiBoot at 15:44, com.tenorshare.AccountMod also at 15:44, iMobie AnyUnlock at
16:30, iMyFone iBypasser at 16:46. Within sixty-two minutes I had installed four
device-unlocking tools, and kept none of them. The files record that hour but
don't say why — which device, what problem, whether it got solved, I don't
know. The hurry of one afternoon is still on the disk; its reason isn't.
The second archive: under ~/Library/Preferences there are thirteen JetBrains
preference domains whose products aren't on this machine — PhpStorm, WebStorm,
PyCharm, Rider, DataGrip, DataSpell, Fleet, Aqua, MPS, Space Desktop, Writerside
and two cwm.guest (Code With Me) variants. Ten of them are from the first
three months of 2025. IntelliJ IDEA and Toolbox are installed, so JetBrains is
here; but I tried those thirteen products and let them go. That list is a tool-shopping history: it
shows what I was looking for, what I tried, and that I liked none of them.
The third is the most personal: com.erpproject.erpProject. That's my own old
app; its container has sat untouched since 5 April 2025. The one developer
leaving leftovers on this disk isn't somebody else.
And com.mojang.minecraftlauncher: 13 March 2025, 578 days. The oldest
untouched leftover on this machine belongs to a launcher installed once to play
a game and then abandoned. The file is 4 KiB. That's the cost of keeping a
record.
Nobody cleans up on Linux either
It would be comforting to think this is a macOS quirk. It isn't.
freedesktop.org's XDG Base Directory specification defines user data under
$XDG_DATA_HOME (default $HOME/.local/share), configuration under
$XDG_CONFIG_HOME ($HOME/.config) and cache under $XDG_CACHE_HOME
($HOME/.cache). It says where things go; it says not one word about what
happens when an application is removed. The specification's only cleanup
language concerns $XDG_RUNTIME_DIR, and that is tied to the session's
lifetime, not to whether an app is installed.
So the same gap exists in both desktop worlds: there is a standard for deleting
the package, and none for deleting the user's data. (I didn't measure Windows,
so I won't speak for it.) There's a sensible side to it as well — if I delete
an app today and reinstall it tomorrow, I don't
want my settings gone either. The policy itself is reasonable; what's missing is any notion of time. In the
system's eyes, "keep it in case they reinstall" and "it's been three years,
still keep it" are exactly the same thing.
Reproducing the number
I don't want the table above to be a closed box for the reader, so here is the
skeleton of the measurement. The first step is the inventory — collecting the
application identifiers that genuinely exist on the machine:
find /System/Library /System/Applications /System/iOSSupport /Library \
/Applications ~/Library ~/Applications /usr/libexec /usr/share \
\( -name '*.app' -o -name '*.appex' -o -name '*.xpc' \
-o -name '*.plugin' -o -name '*.pluginkit' -o -name '*.systemextension' \
-o -name '*.framework' -o -name '*.bundle' -o -name '*.prefPane' \
-o -name '*.qlgenerator' -o -name '*.mdimporter' \) \
-type d 2>/dev/null > /tmp/bundles.txt
wc -l < /tmp/bundles.txt # 23,217 here
Shorten the list of roots or the list of types and the number drops — on the
same machine, removing /System/iOSSupport, /usr/share and the last four
types gives 22,693. In an orphan hunt, a short inventory means extra orphans.
Reading CFBundleIdentifier out of each bundle's Info.plist and
de-duplicating gave me 6,836 identifiers. It's worth adding LaunchServices'
registry on top, because some components are known only to it:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/\
LaunchServices.framework/Support/lsregister -dump \
| awk '/^identifier:/{print $2}' | sort -u | wc -l # 1,070 here
The second step is to list the locations whose names are bundle identifiers and
separate out the ones missing from the inventory. The third step is to verify
each separated name one by one:
mdfind "kMDItemCFBundleIdentifier == 'com.postmanlabs.mac'" # empty here
find /Applications ~/Applications -maxdepth 3 -iname '*postman*' # empty here
du -sk ~/Library/Application\ Support/Postman # 192268
Two lines coming back empty and a third coming back full — that is the
definition of a leftover. The number you get on your own machine will differ
from mine; the thing I'm trying to pass on is the set of filters, not the
number.
How to count on your own machine
I'm writing this as a recipe for counting, not for cleaning. Deleting something
you don't understand is worse than not deleting it.
-
Build the inventory first, then hunt orphans. Don't declare any directory
an "orphan" before you know which application identifiers really exist on the
machine. An
.appscan isn't enough: count the bundles inside.appex,.xpcand.frameworktoo. My container count was inflated sevenfold for exactly this reason: 560 with an incomplete inventory, 77 with a full one. -
Trust only the locations whose names are bundle identifiers.
Containers,Preferences,HTTPStorages,WebKitandSaved Application Stateare like that.Group ContainersandApplication Scriptsare not — the names there are app-group identifiers and match no app at all. - Verify every candidate with a second method. Ask Spotlight by identifier, and search the disk by product name. That's the only thing that separates a helper component of an installed app from a genuine leftover.
- Don't mistake a preference domain for an app — but apply the rule at product level. Libraries like Firebase, Segment and CUPS open preference domains in their own names; those belong to installed apps. The vendor having some other app installed isn't enough on its own: OpenAI's ChatGPT app is on this machine while Atlas isn't, and Atlas is the largest row in the table. The question isn't "is the vendor here" but "is this product's package here".
-
Look at cookie and session files first, size second. Sorting by megabytes
is the wrong instinct. Anything named
Cookies,TransportSecurity,Local Storageorprofilessays more about you than a 4 KiB preferences file does. -
Don't poke at plist files by hand. Apple's
UserDefaultsdocumentation is clear: don't access the files of the defaults database directly from the file system, as it may cause data loss or a crash; on macOS, use thedefaultscommand-line utility. I read file names and timestamps, and never parsed the contents as plists — that was enough for the measurement. - Use the uninstaller when there is one. That's Apple's recommendation, and this is the reason: it's the only thing that takes the items in other locations, like login items and extensions.
-
Be careful with shared directories when deleting. A
Group Containersdirectory is by definition shared between several apps; a directory you delete believing its owner is gone may take the session or settings of a still-installed sibling app with it. That is exactly why I kept that location out of the candidate hunt. - Deleting a cookie doesn't end a session. Revoke the session from the service's account page first, delete the file afterwards.
And one habit worth operationalising: run this pass once a year. The newest
leftover on my list is 93 days old, the oldest 578. An annual pass stops
anything from waiting two years.
Intent doesn't get written to a file
What I took from this count has nothing to do with disk management. Deleting an
app was a sentence for me: "I don't use this any more." The system never heard
that sentence, because what it was told wasn't a sentence — it was a file
changing places. Intent doesn't fit into a file operation.
That's exactly where iOS differs: there, an event called "the last app in this
app group is gone too" exists, which means the system gets a moment in which it
can read my intent. On macOS that moment never arrives. So the 79 traces of 18
apps stayed as a ledger, each line written on its own day and never looked at
again since.
And let me admit something: reading the ledger, I didn't want the space to clear.
Four tools tried and dropped within an hour, twelve JetBrains trials, a
launcher, my own old app — each one is a record of something. Deleting 661 MiB
would take me five minutes. The real issue is that I never decided to keep this
record. When machines decide to remember on our behalf, looking at what gets
remembered is left to us.
Official Sources
- Delete or uninstall apps on Mac — Apple Support
- Install and uninstall apps from the internet or a disc on Mac — Apple Support
- containerURL(forSecurityApplicationGroupIdentifier:) — Apple Developer Documentation
- UserDefaults — Apple Developer Documentation
- XDG Base Directory Specification — freedesktop.org
Top comments (0)