Skip to main content

Want to switch from the Mole Mac site to the Windows site?

Go to the Windows site
Mole
MacWindows
Features Tested apps Testimonials Pricing FAQ Blog
EnglishEN 简体中文中 繁體中文繁 日本語日 한국어한 FrançaisFR DeutschDE ItalianoIT EspañolES PortuguêsPT NederlandsNL
Buy Download

    Help, documentation, releases, and articles.

    Blog

    Making Mole's Uninstall List Appear on Click

    About MolePublished October 28, 20266 min read

    Clicking an app on Mole's uninstall page used to leave the right side blank for a moment, then show "Scanning", and only after half a second to a second did the leftovers appear. Xcode took three to four seconds on every click, ChatGPT six, and scrolling through ChatGPT's expanded list stuttered. I wanted to see where that time actually went, and looked at how a few open-source uninstallers handle the same problem. The changes were finished on October 5 and shipped in Mole 1.16.0; what follows is what I measured at the time and the trade-offs I made.

    The app itself was not the slow part

    I expected bigger apps to be slower, and they were not: a 6.6 MB utility with six leftovers still took about 0.56 seconds on its first click. Most of the time went into a few fixed jobs that ran on every click. These are Release-build medians of three runs on my M5 Pro:

    • Reading Homebrew's cask catalog, a 5.6 MB file, took about 200 ms each time, only to tell whether the app was installed with Homebrew.
    • The app's code signature was validated, twice, at roughly 1 ms per MB of executable; MindNode spent 260 ms on it per click.
    • The slowest scan task was the recent-documents lists: about 230 ms for 775 entries, nearly all of it spent checking paths one by one.

    Some apps added their own cost on top. Xcode's installer receipt is 41 MB and lists 125,000 paths, and it was parsed again on every click. ChatGPT leaves about 15,000 temporary folders behind, and each one had to be checked for ownership on its own.

    What changed

    • The cask catalog is read in the background as soon as the uninstall page opens, not on the click.
    • The click reads the signing information without validating it and pins the app by file identity. Full validation runs in the background after the list appears, and it must finish before anything is deleted.
    • Recent-documents entries are filtered by name first; only those that match go through the full ownership check.
    • The Library roots are listed in parallel, container identities are cached per metadata file, and helper-ID prefixes are worked out once per scan.
    • Installer receipts are cached per receipt file, so a second click on Xcode does not parse those 41 MB again.
    • Temporary folders whose name alone proves who owns them take a fast path; the deletion step still checks every path.
    • Long scan tasks start first, and the hundreds of small ones queue behind them.
    • A scan started by hovering stops when the pointer leaves, and a scan started before an uninstall can no longer write stale results afterwards.

    The easy option for the signature check was to drop it. I moved it after the click instead. When the background validation fails now, the app itself is still uninstalled, and only the kinds of leftovers that were found through the signing information stay behind, such as containers matched by the developer's team ID. The result lists them as "Couldn't verify the app's signature", kept rather than failed. An app that was replaced by a different one after the scan is still refused.

    How much faster

    First click about 1.5 seconds after opening the uninstall page, Release build:

    App Before After
    Shottr 556 ms 137 ms
    MindNode 1233 ms 169 ms
    Raycast 716 ms 171 ms
    Parallels Desktop 871 ms 194 ms
    VS Code 584 ms 232 ms
    WeChat 605 ms 238 ms
    Xcode 3689 ms 384 ms
    ChatGPT 6134 ms 1530 ms

    Most common apps now land under 250 ms, so the leftovers appear in one step without a "Scanning" label first. The background signature validation finishes 12 to 434 ms after the list appears.

    ChatGPT's fifteen thousand rows

    With the clicks fast, scrolling an expanded ChatGPT still stuttered. It listed 15,175 rows, and 15,143 of them were temporary folders shaped like T/.com.openai.codex.XXXXXX, 1.0 GB in total, a few more left behind every time the app launches. Hina, an app I make, was similar: 323 of its 344 rows were Hina-<Suite>-<UUID>.plist files left by test runs, 0.01 MB together. In both cases one randomly named shape filled almost the whole list.

    The row count was not the only cause. The expanded row re-sorted every leftover each time it redrew, and hovering redrew the whole app row, so every row that slid under a still pointer triggered another sort. Rendering the real ChatGPT data, one redraw went from 309 to 354 ms down to 56 to 58 ms, Hina from 33 to 36 ms to 17 to 19 ms, and ChatGPT's expanded height shrank from 3200 pt to 1225 pt.

    Rows now share one line when they have the same category, folder, owner and default selection, and their names differ only in a part the app generated: a random suffix, a UUID, a long hex run or a crash-report timestamp. The shared line keeps the category label, shows the path with * in place of the changing part, followed by the item count and total size, with a single checkbox, and it does not expand. ChatGPT went down to 33 rows across 13 categories, Hina to 24.

    The same ChatGPT leftovers before and after: before, every temporary folder has its own row; after, they share one row reading 15,143 items and 1.02 GB, with the remaining leftovers listed by category.
    The same ChatGPT leftovers, one row per temporary folder before, one shared row after.

    Siblings with names of their own keep separate rows, such as ChatGPT's seven Electron caches, GPUCache, Code Cache, Crashpad and the rest. Merging those as well would have left Hina with about seven rows, which no longer looks like a thorough cleanup; a dozen or so is about right. A name carrying a six-letter word, such as T/<id>.helper, also stays on its own row, because six letters alone cannot be told apart from a random suffix.

    Two earlier attempts stayed rejected. One nested a foldable group inside the already expanded app row; it was tried on September 30 and removed on October 2, because it put folding inside folding and split similar paths between the group and loose rows. The other showed one row per category; it was used on September 4 and reversed a week later, because it hid separate locations behind one line.

    How other uninstallers do it

    Pearcleaner lists about 62 roots concurrently and matches by name, with no ownership proof and no cache; it is fast because it does less. Tencent Lemon works out every app's leftovers when you enter the page and refreshes daily, so clicks are instant, at the cost of a large background scan on every visit, which goes against Mole's rule of adding no resident work. MangoDisk, Uninstally and the Mole CLI use fixed roots with bounded concurrency.

    None of them had a faster underlying primitive than the getattrlistbulk and readdir Mole already uses. I tried Spotlight too: each query took 0.3 to 0.4 seconds and missed most leftovers, finding one of VS Code's four, while searchfs works on APFS but takes about 15 seconds per query. So the work came down to removing repeated jobs from the scan Mole already had. For how to read that leftover list before you delete anything, see Mac uninstall leftovers: review before you delete.

    Mac running low on space or slowing down? Mole can clean out the junk, remove apps completely and keep macOS in shape.

    Try Mole

    Keep reading

    • About MoleMole CLI vs Mac App: Free Terminal or Paid GUI8 min read
    • About MoleAfter Resending 400 Mole License Emails5 min read
    • About MoleFewer Settings, Clearer Choices4 min read

    Mole · 鼴

    Cleanup, software, and status for your Mac.

    v1.19.0 (348) · Release notes

    Product

    Mac Cleaner App Uninstaller Mac Optimizer Disk Analyzer System Monitor

    Support

    Help Documentation Releases Blog

    Legal

    Terms of Service Privacy Policy Refund Policy

    Resources

    For Windows CLI Tool Affiliate Program

    Connect

    Twitter hi@mole.fit

    Mole’s only official website mole.fit · Avoid installers from unknown sources

    The CLI stays free for terminal workflows.