WordPress Space Cleanup: A Free WordPress Database and Media Library Cleanup Plugin

If you run a WordPress site for any length of time, the database quietly fills with junk. Post revisions stack up every time you hit Save. Drafts you abandoned years ago sit there. Spam comments accumulate. Transients expire but never get deleted. Orphaned metadata from plugins you uninstalled months ago quietly occupies table rows nobody ever queries. On a busy blog or a site that has been running for several years, this accumulation can add up to tens of thousands of rows and hundreds of megabytes of wasted space.

I built CloudScale Cleanup to deal with this properly. It is a free, open source WordPress plugin that handles both database cleanup and media library cleanup — unused images, orphaned filesystem files, and image optimisation — through a clean admin interface with full dry run support so you can see exactly what will be deleted before anything is touched.

You can download it here: cloudscale-cleanup.zip

What It Cleans

Database Cleanup

Post Revisions — Every time you update a post, WordPress stores a complete copy of the previous version. On an active blog this means hundreds of revision rows per post. CloudScale Cleanup removes revisions older than a configurable threshold (default 30 days), leaving recent ones intact.

Draft Posts — Posts saved as drafts but never published. The threshold (default 90 days) ensures you never accidentally lose something you were actively working on.

Trashed Posts — Posts moved to the WordPress trash. WordPress keeps them indefinitely. The plugin removes them after a configurable number of days.

Auto-Drafts — WordPress creates an auto-draft record every time you open the Add New Post screen. If you navigate away without saving, the empty record remains. These accumulate silently and are almost always safe to delete immediately.

Expired Transients — Temporary cached values stored in your options table by plugins and themes. After expiry WordPress should delete them, but many are never cleaned up. They are completely safe to delete and can number in the thousands on plugin-heavy sites.

Orphaned Post Meta — Metadata rows referencing post IDs that no longer exist. Left behind when posts are deleted without their associated metadata being cleaned up first.

Orphaned User Meta — The same problem for user accounts. When a user is deleted, their metadata rows often remain.

Spam Comments — Comments flagged as spam. A configurable threshold (default 30 days) gives you time to review false positives before they are permanently removed.

Trashed Comments — Comments you have manually moved to the comment trash, removed after a configurable threshold.

WordPress database cleanup interface showing removal options

Image Cleanup

Unused Images — Attachments that exist in your media library but cannot be found anywhere on the site: not in post content, not as featured images, not in widget settings, theme mods, the site logo, or the site icon. The site logo and icon are always protected regardless of settings.

Orphaned Filesystem Files — Image files that exist physically on disk inside wp-content/uploads but have no corresponding WordPress attachment record in the database. These are typically left behind after failed imports, manual file operations, or plugin migrations.

WordPress media library cleanup tool scanning unused images

Image Optimisation

CloudScale Cleanup can resize and re-compress JPEG and PNG images that exceed configurable maximum dimensions or quality thresholds. This is a destructive operation; it modifies the original files on disk; so the plugin requires explicit confirmation and strongly recommends taking a backup first.

WordPress image optimization settings for resizing and compression

Installation

  1. Download the plugin zip from: https://andrewninjawordpress.s3.af-south-1.amazonaws.com/cloudscale-cleanup.zip
  2. In your WordPress admin, go to Plugins → Add New → Upload Plugin
  3. Choose the zip file and click Install Now
  4. Click Activate Plugin
  5. Navigate to Tools → CloudScale Cleanup in the admin sidebar

If you have an opcode cache running (OPcache, Redis object cache, or a caching plugin like WP Rocket or W3 Total Cache), deactivate and reactivate the plugin after installation to ensure the new files are loaded cleanly.

Using the Plugin

The Dry Run

Before deleting anything, always run a dry run. Click the Dry Run — Preview button on the Database Cleanup tab. The plugin will scan your database and report exactly what it found — how many revisions, which draft posts, how many orphaned meta rows — without touching anything.

The output terminal shows each category with a count, and for items like draft posts it lists the individual post IDs, titles, and dates so you can make an informed decision before proceeding.

If a toggle is switched off, the category will show as SKIPPED (disabled) in the output. Toggle states are respected at the point of scanning, so what you see in the dry run accurately reflects what the actual cleanup will do.

Toggles

Each cleanup category has a toggle switch. Green means it will be included in the next scan or cleanup run. Grey means it will be skipped. Toggle settings are saved independently using the Save Selection button on each card.

This lets you permanently disable categories you never want touched — for example, if you deliberately keep old drafts as reference material, toggle off Draft Posts and it will never appear in scans.

Thresholds

The Cleanup Thresholds card controls the age cutoffs for each category. Every threshold prevents the cleanup from touching items that are too recent. Defaults are conservative:

  • Post revisions older than 30 days
  • Drafts older than 90 days
  • Trashed posts older than 30 days
  • Auto-drafts older than 7 days
  • Spam comments older than 30 days
  • Trashed comments older than 30 days

Adjust these to match your workflow. If you publish daily and never need to recover a revision more than a week old, set the revision threshold to 7 days. If you occasionally return to old drafts, set the draft threshold to 180 days or higher.

Running the Cleanup

Once you are satisfied with the dry run output, click Run Cleanup Now. The plugin will ask for confirmation, then process deletions in chunks to avoid PHP timeout limits. A progress bar tracks completion in real time. The output terminal logs each deleted item.

The chunked processing engine means the cleanup is safe to run on large sites. Even if you have 50,000 orphaned meta rows, the plugin processes them in batches of 50 and reports progress throughout rather than attempting a single massive query that could time out.

Scheduled Cleanup

The Settings tab includes a scheduler that registers a WordPress Cron job to run the database cleanup automatically on selected days at a configured hour.

A note on WordPress Cron: it is not a real cron. It is triggered by page visits. On a low-traffic site, a job scheduled for 3:00 AM may not run until the first visitor arrives that morning. For precise scheduling, disable WP-Cron in wp-config.php and add a real system cron:

# wp-config.php
define('DISABLE_WP_CRON', true);
# Server crontab
0 3 * * * curl -s https://yoursite.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Architecture Notes

The plugin is deliberately self-contained — a single PHP file plus two asset files with no external dependencies and no calls home. It uses WordPress’s own $wpdb for all database operations, respects WordPress nonces for AJAX security, and hooks into the standard admin menu and enqueue system.

Cleanup operations use a three-phase chunked engine: a start action builds the queue and stores it in a transient, a chunk action processes one batch and updates the transient, and a finish action reports the final summary and cleans up. This pattern means the browser never waits more than a few seconds for any single request, and the cleanup can handle arbitrarily large datasets without running into PHP execution time limits.

The toggle state is passed from the browser to the PHP handler on every scan and run request. The PHP handler never assumes toggles are on — if a key is missing from the POST data it treats that category as disabled. This means the dry run and the actual cleanup always respect the current on-screen state, not just whatever was last saved to the database.

Download

The plugin is free and open source.

Download CloudScale Cleanup v1.5.3

Install it, run a dry run, and find out how much cruft has been accumulating in your WordPress database.

Leave a Reply

Your email address will not be published. Required fields are marked *