Home › Blog › Article

Taming the WordPress Media Library: Sizes, Formats and Legacy Cleanup

Taming the WordPress Media Library: Sizes, Formats and Legacy Cleanup

Compress images before upload, define a strict thumbnail size strategy, scan for orphaned files, and verify references before deleting anything. You know it worked when new uploads are under your size budget, wp_posts attachment rows match real files, no 404s appear in the browser console, and your Largest Contentful Paint improves in PageSpeed Insights. This tutorial gives you copy-pasteable commands and rollback paths.

Prepare: Environment and Baseline

Before touching media, take a full backup and record current metrics. On the server, dump the database and archive wp-content/uploads:

mysqldump -u DB_USER -p DB_NAME > /root/media-backup-2026.sql
tar -czf /root/uploads-backup-2026.tar.gz wp-content/uploads

Note your current media library size in the WordPress admin under Tools → Site Health → Info → Media, and record LCP from WordPress performance documentation. If you run a managed build, see our notes on monitoring a WordPress site to track regressions. Also confirm you are on WordPress 6.8 or later (2026 core) so the REST media endpoints return full size metadata.

Step Process: The Cleanup Workflow

  1. Compress every image before it reaches the media library.
  2. Define and register your thumbnail size strategy in theme code.
  3. Scan the filesystem and database to find unused images.
  4. Check every reference before deleting any attachment.
  5. Delete safely and regenerate missing sizes.
  6. Verify with SQL and browser tools, then roll back if broken.

Compressing Before Upload

The cheapest byte is the one you never upload. WordPress generates multiple sizes from the original, so a 4 MB JPEG becomes maybe 8 files totalling 6 MB. Compress at the source with sharp in Node 20+ or cwebp from libwebp 1.3 (2026 stable). Install CLI tools:

apt-get install -y webp jpegoptim optipng
npm install -g sharp-cli

Batch convert legacy assets

Run this in the uploads root to make WebP copies and shrink originals:

find wp-content/uploads -type f ( -name '*.jpg' -o -name '*.jpeg' ) -exec sh -c 'cwebp -q 82 "$1" -o "${1%.*}.webp" && jpegoptim --max=85 --strip-all "$1"' _ {} ;

Get a Quote

Email + requirement + budget range — we reply with a quote within 24 hours.

Why: jpegoptim --max=85 caps quality, --strip-all removes EXIF. Verify with identify -format '%b %fn' file.jpg from ImageMagick 7.1. Pitfall: stripping EXIF kills copyright data; keep --strip-com only if you need IPTC. Rollback: restore from uploads-backup-2026.tar.gz.

Thumbnail Size Strategy

Never rely on defaults alone. Register explicit sizes in your child theme functions.php so the media library only builds what your layout uses:

add_action( 'after_setup_theme', function() {
    add_image_size( 'card-thumb', 400, 300, true );
    add_image_size( 'hero-lg', 1600, 900, false );
    update_option( 'thumbnail_size_w', 150 );
    update_option( 'medium_size_w', 600 );
    update_option( 'large_size_w', 1200 );
} );

Then disable unused defaults with remove_image_size( 'medium_large' ) after after_setup_theme. Why: each extra size multiplies disk and backup weight. Verify in the database:

SELECT meta_value FROM wp_postmeta WHERE meta_key = '_wp_attachment_metadata' LIMIT 1;

The serialized array should list only thumbnail, medium, large, card-thumb, hero-lg. Pitfall: changing sizes does not rewrite old files; run wp media regenerate --yes with WP-CLI 2.10 (2026). Rollback: comment the block and regenerate again.

Finding Unused Images

Unused images are attachments not referenced in post_content, postmeta, options, or theme files. Query the DB for candidates:

SELECT p.ID, p.post_title, pm.meta_value AS file
FROM wp_posts p
JOIN wp_postmeta pm ON pm.post_id = p.ID AND pm.meta_key = '_wp_attached_file'
WHERE p.post_type = 'attachment'
AND NOT EXISTS (
  SELECT 1 FROM wp_posts c
  WHERE c.post_content LIKE CONCAT('%', pm.meta_value, '%')
);

Export that list to CSV. Cross-check with a filesystem scan using find wp-content/uploads -name '*-scaled.*' and compare against the REST endpoint /wp-json/wp/v2/media?per_page=100. Why: SQL alone misses hardcoded theme paths and widget HTML. Pitfall: _wp_attached_file stores relative paths, so LIKE matching must use the value not the GUID. Rollback: you have the CSV plus the tarball.

Checking References Before Deleting

Deleting an attachment row without checking usage causes 404s and broken layouts. For each candidate ID, search every table:

wp db query "SELECT * FROM wp_postmeta WHERE meta_value LIKE '%2026/05/photo.jpg%'"
wp db query "SELECT option_name FROM wp_options WHERE option_value LIKE '%photo.jpg%'"
grep -r 'photo.jpg' wp-content/themes wp-content/plugins

Also check wp_term_taxonomy descriptions and WooCommerce product galleries via _product_image_gallery. Why: a featured image ID in _thumbnail_id is invisible to content LIKE scans. Verify with SELECT post_id FROM wp_postmeta WHERE meta_key='_thumbnail_id' AND meta_value=ID. Pitfall: multisite stores uploads under /sites/2/; adjust paths. Rollback: re-import the SQL dump rows for that ID.

Delete and Regenerate

Delete and Regenerate

When references are zero, delete with WP-CLI so metadata and files both go:

wp post delete 123 --force --yes
wp media regenerate --yes --only-missing

--only-missing (WP-CLI 2.10) skips existing sizes. Then flush Redis/Varnish with wp cache flush. Verify HTTP 200 on old URLs returns 404 and no console errors. If you need a rebuild partner, our team handles this in custom WordPress development engagements. For broader planning see how to build a website with WordPress.

Verify and Roll Back

Open DevTools Network, filter Img, and confirm zero 404s. Run wp media list --fields=ID,file and compare count to your CSV. If something breaks: tar -xzf /root/uploads-backup-2026.tar.gz then mysql DB_NAME < /root/media-backup-2026.sql. Check Site Health again; LCP should drop.

Action Checklist

  • Back up DB and uploads before any change.
  • Compress with cwebp and jpegoptim pre-upload.
  • Register only needed image sizes in functions.php.
  • Run the orphan SQL query and grep themes/plugins.
  • Delete via WP-CLI and regenerate missing sizes.

Need a production-safe media audit? Our engineers clean libraries without downtime. See our WordPress development services for a fixed-scope cleanup.

Frequently asked questions

Does compressing before upload hurt SEO image quality?

No. Quality 82 WebP is visually lossless for most screens and cuts bytes by 30–50%, improving LCP which search engines measure.

Can I delete unused images straight from the Media Library UI?

You can, but the UI does not grep theme files or options. Use the SQL and grep method above to avoid silent breakage.

What if regeneration times out on a large library?

Run wp media regenerate --yes in a tmux session or chunk by year folder to avoid PHP max_execution_time limits.

References & further reading

Need WordPress Development?

Free proposal and quote within 24 hours — we serve clients worldwide.

QQ