Getting started

Freshet Unused Media answers one question about every file in your media library: is this still used anywhere? — and lets you delete the files that provably aren't.

WordPress' own Uploaded to column only records where a file was first attached. It says nothing about where a file is actually used, so an image referenced from a custom field, a page builder, a widget or a plain URL looks exactly like a file nothing needs. This plugin looks in all those places instead, and shows you the evidence for each answer.

Requirements

GPL-2.0-or-later. This page documents 1.0.1.

Install

Upload the plugin and activate it. Nothing is scheduled, nothing runs on its own, and no tables are created — a scan happens when you start one.

Before your first run, consider adding a trash safety net to wp-config.php:

define( 'MEDIA_TRASH', true );

With that set, a deletion here goes to the media trash and can be restored. Without it, deletion is permanent — see Deleting safely.

The screens

Everything lives under Media → Usage, plus two additions to screens you already use:

Where What
Media → Usage → Scan Start, resume, stop or reset a full-library scan; running totals of used, unused and not-yet-scanned
Media → Usage → Unused The list of files nothing refers to, with filters, and the delete actions
Media → Usage → Used Every place a used file is used [Pro feature]
Media → Usage → License Enter or remove a key (only in the build downloaded from freshet.studio)
Media Library, list mode A Usage column with a badge, a per-file Check usage action, and a status filter
The attachment screen A Usage meta box listing the references found, each with a link to go and look

Your first scan

  1. Go to Media → Usage.
  2. Press Start full scan. The page walks your library in batches and shows progress as it goes.
  3. Leave the tab open, or don't — the scan records its position after every batch. Resume scan picks up from the last completed file rather than starting over.

Each batch stops before PHP's time limit is reached, so a batch can never run out of time mid-file and retry the same IDs forever. That is what makes a large library safe to scan in a browser at all.

It takes as long as it takes

Thoroughness is the point rather than speed: a first full scan of a large library is measured in hours, not minutes. Cost tracks the total volume of content the scan has to read through rather than the number of files — a library of a few thousand attachments on a site with a few thousand page-builder posts is an afternoon's work, not a coffee break. A scanner that only reads the Uploaded to column is much faster and answers a much weaker question.

Nothing is lost to that time. The scan always makes progress, it can be stopped and picked up later, and the results are stored per file as they are computed — so the second scan of a library only has to catch up on what has changed.

Reading the result

Every scanned file ends up in one of three states:

The status shown against a file records what the last scan found. If the content has changed since, the Scan tab and the meta box both say so rather than presenting a stale answer as current.

A file being used is never a judgement about whether you want it — it means something on the site still points at it. What counts as a reference, and the deliberate places the plugin errs towards keeping a file, are on How detection works.

Next: How detection works.