We’ve all been there. You have a specific problem to solve—maybe a complex shipping calculator or a new gallery layout—so you head to the WordPress.org repository. You download three different plugins, test them out on your live site, find the winner, and delete the other two.
Problem solved, right? Not exactly.
While the plugin might be gone from your “Plugins” menu, there is a high statistical probability that it left behind “scraps of data” in your database—orphaned settings, expired transients, and abandoned metadata that will sit there until the end of time.
The “Uninstall” Problem
WordPress has long provided a standard for a clean exit: the uninstall.php file. When a developer includes this, WordPress runs it during deletion to scrub the database.
However, many developers don’t use it. Sometimes it’s a lack of awareness; other times, it’s a strategic choice. They worry that if a user uninstalls by mistake and loses all their settings, it becomes a support nightmare. The result? The “Option Hide” problem. Even when a plugin does offer a “Delete data on uninstall” toggle, it’s often buried deep in a settings menu where no user ever thinks to look before hitting “Delete.”
By the Numbers: The State of the Repository
Note: This was a first attempt using AI, and I am sure these numbers are off a bit, but it is enough to show the problem.
To understand the scale of this issue, I built the WordPress Plugin Uninstaller Generator—a high-performance toolkit designed to analyze the entire WordPress.org repository.
After processing 43,640 valid plugins, the data is staggering:
- 83% of plugins do not provide an
uninstall.phpscript. - Over 40% of plugins natively “litter” the database with orphaned data.
- Only 28.6% of plugins were found to be “Clean by Default” (leaving nothing behind).
Where is the mess coming from? Here is what my analysis found across the repository:
While some offenders are small, others might be industry giants. Heavyweights like various exporters top the list of items left behind, often due to the sheer complexity of the data they handle.
Automating the Solution
I wanted to do more than just point out the problem; I wanted to automate the solution.
The WP Plugin Uninstaller Generator is a TypeScript-based engine that uses Abstract Syntax Tree (AST) parsing. It doesn’t just “guess” what a plugin does; it reads the code:
- Direct Streaming: It streams plugin ZIPs directly from WordPress.org into memory (no disk writes required).
- Code Analysis: It parses every PHP file to find function vectors like
add_option,set_transient, and$wpdb->query. - Artifact Generation: It automatically generates three ways to clean up:
uninstall.php: A drop-in file for developers or advanced users.uninstall.sql: For direct database cleaning via phpMyAdmin.uninstall.sh: A WP-CLI script for terminal power users.
Why This Matters
A bloated database isn’t just a “neatness” issue. It can lead to:
- Slower Backups: Larger SQL dumps take longer to move and store.
- Performance Degradation: Autoloaded options from deleted plugins still load on every single page hit.
- Site Fragility: Orphaned cron jobs trying to call functions that no longer exist cause unnecessary overhead.
Ideas for the Future
- Improve the tooling that performs the check to prevent false positives.
- Use Docker or WordPress Playground to do more real-world testing.
- Add checks for Custom Post Types and Custom Taxonomies (e.g. if you uninstall WooCommerce, why keep 150 orphaned products in your database?).
- Build a plugin that scans the database for scraps and reports/uses the uninstall scripts generated in this repo.
Check out the repo on GitHub: bhubbard/wp-plugin-uninstalls
Let’s start treating the WordPress database with a bit more respect. Our load times will thank us.