If you have been running a WordPress site for a year or more, there is a good chance your media library holds files no page is actually using. Leftover thumbnails from deleted posts, images swapped out during a redesign, assets from a builder experiment that never shipped. They accumulate quietly, and at some point a routine cleanup turns into a broken page because the wrong file got deleted.
This guide walks you through how to find, verify and delete unused media files safely, in that exact order.
What “unused” actually means (and why getting it wrong breaks your site)
Before touching anything, it is worth understanding what WordPress tracks and what it does not.
In WordPress, every uploaded file is registered as an attachment: a post type with its own database entry. When you delete a page or a post, WordPress does not automatically remove the media that was used in it. The files stay on the server, the database records remain and nothing points to them anymore. These are the cleanest candidates for deletion.
The trap is the word “unattached.” WordPress marks an image as unattached when it has no parent post in the database, which happens when it was not uploaded from within a specific post’s edit screen. An unattached image can still be actively displayed on dozens of pages, in a theme header, a widget, a builder block or a plugin setting. Deleting based on the unattached filter alone is one of the most common ways cleanups go wrong.
If you want to understand in detail why the unattached filter is not a reliable signal, and how to build a candidate list before you delete anything, see: WordPress find unused media: the safe way to spot orphan files.
Where images can hide on a WordPress site
The WordPress media library only shows what it was designed to track. Images are actively used in far more places:
- Post and page content (classic editor and Gutenberg block attributes)
- Page builder settings (Elementor sections, Divi modules, background images)
- Theme customizer options (site logo, background image, header)
- Widget content and sidebar HTML
- Custom fields and ACF metadata (including repeaters and option pages)
- WooCommerce product galleries and variant images
- Plugin settings, sliders and gallery shortcodes
- Custom CSS and inline styles
A file can be in none of those locations, or in all of them. WordPress itself does not give you a unified view across all of them. That is the gap the safe deletion workflow addresses.
Before you delete anything: the safety checklist
Media deletion in WordPress is permanent. There is no native trash for media attachments. One wrong click and the file is gone from every post, page or template it appeared on, replaced by a broken image. Work through this checklist before any cleanup session, and begin with a full backup.
- [ ] Full backup complete, covering both files and database
- [ ] Restoration tested (at minimum, confirm the backup opens and is not empty)
- [ ] Staging environment used if the site is in production
- [ ] Candidate list ready: files identified for deletion, not yet deleted
- [ ] Starting with a small batch (10 to 20 files, not hundreds)
- [ ] Key pages noted for post-delete verification
Step 1: find unused media candidates
The goal of this step is to build a candidate list, not to delete. A candidate is a file you suspect is unused, not one you have confirmed.
Method A: the native filter (quick first pass)
In the media library, switch to list view and use Filter by type → Unattached. This surfaces files with no parent post relationship in the database.
Use this as a starting point only. Every file in this list needs to be verified before it goes near a delete button.
Method B: plugin with a real usage index (recommended)
At any volume above a few dozen files, manual verification of the unattached list is not practical. More importantly, it leaves blind spots the filter cannot address: builder blocks, ACF fields, custom options, theme settings.
Mediapapa builds a usage index that tracks every file across all of these locations, covering posts, ACF fields, option tables, Gutenberg block attributes, Elementor data and more. When it surfaces a file as unused, it has verified your entire site, not just the fields WordPress exposes natively.
The Library Health dashboard then groups findings by priority, so you are not staring at a flat list of thousands of files trying to decide where to start.
On top of unused media detection, Mediapapa adds Deletion Warnings: if you attempt to delete a file that is still in use somewhere, it stops you before the deletion executes and shows you exactly where the file is referenced. WordPress has no equivalent, since a native delete is immediate and silent.
Method C: WP-CLI (for large or developer-managed sites)
WP-CLI is the appropriate level of tool for high-volume sites: WooCommerce stores with thousands of product images, news archives, large multisite installs. It lets you run media queries as background processes without browser timeouts.
wp media list --post_status=any --fields=ID,post_title,attachment_url
This produces a raw list of registered attachments to cross-reference against your content. It is a starting point for developers comfortable querying wp_posts and wp_postmeta directly. Blind spots include serialized data, theme customizer options and hardcoded URLs in templates, which require separate checks.
Step 2: verify each candidate is actually unused
This is the step most guides skip, and the step that prevents broken pages.
For each candidate file, run the following proof check.
The proof workflow
Check the file URL in your content. Copy the full attachment URL from the media details panel. In the WordPress block editor, use the search function. In the database, search wp_posts.post_content for the URL string.
Check post meta and custom fields. If you use ACF, theme options or any plugin that stores data in wp_postmeta or wp_options, a simple content search will not surface these. This is where the native method has its most significant blind spot.
Check the theme customizer. Open Appearance → Customize and look through logo, background image and header settings. These are stored in wp_options under theme_mods_{themename} and will not appear in a content search.
Check widget content. Go to Appearance → Widgets (or the block-based widgets screen) and scan for any image blocks or HTML widgets referencing the file.
Check builder settings. If you use Elementor, Divi or similar tools, open a few key pages and inspect section background images, image widgets and popup triggers. Builders often store these references in serialized data that is invisible to a plain text search.
Special cases worth flagging separately
Featured images. A featured image is stored in wp_postmeta as _thumbnail_id, not in post content. It will appear as unattached in the media library filter even if it is the hero image on your homepage.
PDFs and downloadable documents. A PDF with no database parent could be linked from an email newsletter, an external site or a pinned social post. Deletion removes the source file immediately. Check referrer data in your analytics before acting.
WooCommerce product images. Variant images, gallery images and product thumbnails are stored in product meta, not post content. A standard content search will not find them. Always use a tool with WooCommerce-aware scanning for shops.
Step 3: delete safely (in batches)
Once you have a verified list of files confirmed unused across all the locations above, you can proceed with deletion. The method matters as much as the list.
Work in small batches
Delete 10 to 20 files at a time, then check your site before continuing. This is the only way to isolate a mistake before it multiplies. A bulk delete of 500 files leaves you no way to identify which one caused a broken image three posts later.
Verify the site after each batch
After each deletion pass, check the following pages manually:
- Homepage
- Main category or archive pages
- Top-traffic posts (use Google Analytics or Search Console to identify them)
- Any page that uses the header, footer or global template components
- Checkout and product pages if you run WooCommerce
What to look for: missing images, broken image icons in the browser, layout shifts from missing background images.
Check for 404 image errors
After the first batch, open your browser’s developer tools on a few key pages and check the Network tab filtered to images. Any 404 response on an image URL indicates a deletion that broke something. Catching these early makes correction straightforward.
Do not forget thumbnails and size variants
When WordPress registers a deleted attachment, it should cascade the deletion to all generated size variants. Most cleanup plugins handle this correctly. If you delete files manually via the WordPress admin or FTP, verify that the variants (image-300x200.jpg, image-1024x768.jpg and so on) are also removed.
CDN and caching note
If you serve images through a CDN, deleting the source file does not automatically purge the cached version at the edge. After a cleanup session, purge your CDN cache manually. Until you do, posts and pages may appear intact while actually serving files that no longer exist on the origin.
Step 4: clean up leftover files on the server
Deleting a media attachment in WordPress removes the database entry and, in most cases, the file itself. In some situations, however, files remain in /wp-content/uploads/ after the attachment record is gone.
When files stay after deletion
This happens most often after plugin migrations, CDN sync errors, bulk import tools that bypassed the WordPress media registration flow or manual FTP uploads that were never registered as attachments. These files exist on the server but have no corresponding entry in wp_posts, meaning WordPress is unaware of them.
Before removing anything at the server level, confirm that a file has no corresponding attachment record and is not referenced anywhere in your database. Deleting files directly via FTP or your host’s file manager is irreversible and bypasses any plugin safety layer.
How to identify true server orphans
The most reliable approach is to compare your /wp-content/uploads/ directory against the list of registered attachment URLs. WP-CLI makes this practical for large sites:
wp media list --post_status=any --fields=attachment_url --format=csv
Export that list, then compare it against your uploads folder contents. Files present on the server but absent from the list are candidates for review. Verify each one before acting: a file absent from the attachment list could still be hardcoded into a theme template or referenced in a plugin configuration file.
After server-level cleanup
Run a broken link scan across your site after any server-level file removal. Tools such as Google Search Console (under Coverage and Experience) or a plugin-based link checker will surface any 404 responses caused by files that were still in use somewhere.
Step 5: prevent the next round of accumulation
A single cleanup is worth doing. A cleanup paired with a governance routine is effortless to maintain.
Four habits that keep the library clean
Name files before uploading. team-photo-2025-homepage.jpg is findable. IMG_4892.jpg is not, and it will be the one you cannot identify two years later.
Scan before re-uploading. Duplicate images are one of the most reliable sources of library bloat. Use the media library search to check whether an asset you need already exists before uploading a new version.
Delete media when you delete content. When removing a post or a product for good, take 60 seconds to check whether its featured image and gallery images are used anywhere else. If not, delete them in the same session.
Use a quarterly routine. Once per quarter: run an unused media scan, review the Library Health score in Mediapapa, delete confirmed candidates in small batches. A regular cadence keeps the volume of each session manageable and the library in good shape long-term.
FAQ
No. Unattached means an image has no parent post relationship in the WordPress database, typically because it was uploaded directly to the media library rather than from within a post’s edit screen. It can still be actively displayed in a widget, a theme setting, a builder block or a custom field. Always verify before deleting.
The most likely cause is that the image was in use somewhere the deletion check did not cover: a builder background image, a widget, a custom field or a theme option. WordPress does not warn you when you delete a file that is still referenced. This is exactly what Deletion Warnings in Mediapapa prevents.
Copy the full file URL from the media details panel and search for it in your post content. For a complete picture including custom fields, theme options and builder data, use a plugin with a proper usage index, since native WordPress search covers only post_content.
Both builders store image references in their own data formats, often serialized in wp_postmeta. A standard WordPress content search will not surface these references. Mediapapa’s usage index covers Elementor blocks and options. For Divi, verify manually in the builder before deleting any candidate that could be a background or section image.
Not directly. Unused files in /wp-content/uploads/ are not rendered on the front end and do not affect page speed or crawl budget on their own. The real gains come from the habits that accompany a cleanup: removing oversized images, converting to WebP or AVIF and completing missing alt texts, all of which do affect page performance and accessibility.
Not through WordPress itself. Once permanently deleted, there is no native recovery path. This is why taking a full backup before any cleanup session is the first item on the checklist. If you use a plugin with soft-delete or staging workflow support, recovery is possible within the retention window. Check your plugin’s documentation for details.
No plugin covers 100% of edge cases. Files hardcoded into theme templates, referenced in external email newsletters or linked from third-party sites are outside the scope of any database-level scan. The proof workflow in Step 2 exists precisely to catch these cases before deletion.
A quarterly routine is enough for most sites. High-volume sites, active news publications and WooCommerce stores with frequent product turnover benefit from a monthly pass. Tracking your Library Health score over time gives you an early signal when accumulation is building before it becomes a maintenance problem.
Additional reading
- Use image and file attachments — WordPress.org official documentation on how attachments work in WordPress
- Media Library screen — WordPress.org official reference for the media library admin interface
- Tracking media usage and Deletion Warnings — how Mediapapa’s usage index and Deletion Warnings work
- Understanding Media Scores in Mediapapa — Media Score and Library Health explained
- Detecting and removing duplicate images — the deduplication workflow in Mediapapa


