Deleting safely

Deletion happens in one place — Media → Usage → Unused — and only when you ask for it. Nothing is deleted on a schedule, nothing is deleted by a scan, and there is no delete verb on the command line. This page is the one to read before you press anything.

The two actions

Delete selected — tick the rows you want and press it. The button sits above and below the table, so it is in reach from either end of a long list.

Delete all unused (400) — the button on the heading row, deliberately styled as a destructive link rather than as the screen's primary action. The number in the label is the set it will act on.

Both re-check first (below), both report what happened, and both obey the media trash.

Filters, and why the button label changes

Above the list there is a filter bar: uploaded from / to, filename contains, min size, max size. It is a plain GET form, so the URL is the filter state — it survives pagination and can be bookmarked.

When a filter is active, three things change together:

A control that still said all over a screen showing a subset is exactly how the wrong files get deleted, so it doesn't.

One caveat the screen states for itself: while a size filter is applied, files whose size cannot be read are left out of the list rather than being counted as zero.

Every file is re-checked in the instant before it goes

The list you are looking at reflects the last scan. Between that scan and your click, someone may have placed one of those files in a post.

So the delete pass does not trust the list. Each ID is scanned again, right there, and anything that has become used is skipped rather than deleted. The result says so:

Deleted 12, skipped 1 (found in use on re-check), failed 0.

Every confirmation dialog states the promise before you accept it:

Each one is re-checked first; anything still in use is skipped.

One honest limit: the re-check is not atomic. A reference written in the fraction of a second between the re-check and the deletion is not seen. The upload grace covers the realistic version of that race — a file placed in the editor before its post is saved — and MEDIA_TRASH covers the rest.

Trash, or permanence

The plugin has no trash of its own and does not want one. It respects WordPress'.

With MEDIA_TRASH enabled, deleted files go to the media trash and every confirmation ends:

Deleted files go to the media trash and can be restored from there.

Without it, deletion is permanent, and the confirmation says exactly that:

Deletion is permanent and cannot be undone.

The Unused tab also carries a standing notice above the list when there is no safety net: MEDIA_TRASH is not enabled — deletions are permanent. Add define( 'MEDIA_TRASH', true ); to wp-config.php to get a trash safety net.

That is the whole safety story, and it is deliberately short: respecting the setting WordPress already has, and saying which side of it you are on at the moment you press the button. If you are about to clean a library you cannot re-upload, enable it first.

What deletion does and does not touch

Before a big clean-up

  1. Enable MEDIA_TRASH, or take a backup you have actually restored from before.
  2. Run a full scan and let it finish — the Not scanned count on the Scan tab should be zero.
  3. If a plugin on your site keeps media references in its own tables, check what it holds (the blind spot).
  4. Spot-check a handful of files on the Unused list: open one, read the Usage box, agree with it.
  5. Then delete — filtered first, if you want to start small.

Next: What a license adds.