Freshet Studio Unused Media

Plugin

Freshet Unused Media Pro

The gripe

I can't reliably clean up the media library, because WordPress cannot tell me whether a file is in use.

The plugin

Should look everywhere a reference can hide, and show me the evidence it finds, instead of guessing.

The Uploaded to column records where a file was first attached and nothing more. So an image used in an ACF field, a page-builder shortcode, a customizer setting or a plain URL in content looks exactly like one nothing has pointed at in years.

Every media cleaner has to answer the same question: is this file safe to delete? This one answers it by looking everywhere a reference can hide, showing its evidence, and refusing to guess.

Free, and the whole plugin

Scanning, detection and deletion are free and stay free. Nothing in the download is locked, limited or time-barred.

It finds references nothing else looks for
ACF fields, galleries and repeaters — checked against ACF's own field keys — ACF block markup where no URL is ever written, Elementor data, term and user meta, term descriptions, comments, widgets, theme mods, autosaved edits, and raw URLs including resized variants and -scaled files. Read the technicalities in the docs.
It is built to be wrong in one direction only
Ambiguity counts as used. A reference from a trashed post still counts. Files uploaded in the last 24 hours are held back. Attachment 123 is never matched by wp-image-1234.
Every file is re-checked in the instant before it is deleted
Anything that became used between the scan and your click is skipped rather than deleted — and the result tells you how many.
The evidence is shown, not summarised
Every reference is listed with the object it lives in, the field it was found in, and a link to go and look — so you can check the reasoning before acting on it.
The blind spot is written down
References held inside a plugin's own custom database tables cannot be found by any query-based scanner. That limit is documented rather than left for you to find out — and it is not the end of the conversation: freshet_unusedmedia_detectors lets you add a detector of your own that queries your table and reports back like any built-in one. The hook reference is in the docs.
Measured on a real library, not a demo site

A real agency-managed WordPress library: 38,797 attachments accumulated over eight years, ten gigabytes of uploads, 3,656 distinct files on disk (the site is multilingual, so one upload carries about ten library rows). WordPress' own Unattached filter marks 23,659 of those rows — three in five — as apparently free to delete.

The scan says otherwise. On a random sample of 450 files, about one in eight of the library, 438 turned out to be referenced somewhere WordPress does not look — page content, featured images, block fields, theme options — and 12 came back with no reference at all. Of the Unattached rows in that sample, 98% sat on a file the site still uses. Deleting on WordPress' own signal would have taken live files with it nearly every time; the scan narrows the job to the 3% that can go.

Looking that carefully has a cost: about 14 seconds per file on a laptop, so a first full pass of a library this size is an overnight job — around fourteen hours. Later scans are quick. Nothing was deleted while measuring: the scan ran on an offline copy, scan only. The full write-up is on the blog.

Needs WordPress 6.5 and PHP 8.1 or newer. Download it from wordpress.org, or read the source on GitHub. Or Try it in WordPress Playground first: a throwaway site in your browser, the plugin active and a media library already seeded to scan.

What Pro gets you

Four additions. None of them deletes anything.

The Used view

See every place a file is used. Useful where you want to replace rather than remove. You get the full list of what would break, before you touch anything, and something to hand over in case it needs to be signed-off.

WP-CLI

wp freshet-unusedmedia scan and list — the same scan across many sites without a browser, read back as JSON.

Evidence report

Export the library as CSV or JSON: one row per file, with its status, its size and where it was found.

Space totals

How much disk the unused files are holding now, and separately, how much has actually been freed by the deletions made here.

EUR 149.00 (about $172), once

Secure checkout via Stripe.
On screen licence key and in your inbox the moment payment clears.