--- title: "Find unused WordPress plugins: an audit tool you can build today" description: Inherited a WordPress site with too many plugins? This audit tool scans for usage signals and highlights the ones with no detectable footprint. source: https://steem.dev/blog/wordpress-find-unused-plugins-audit-tool published: 2026-10-20 updated: 2026-10-20 site: Steem — AI WordPress plugin generator --- # Find unused WordPress plugins: an audit tool you can build today When you inherit a WordPress site, the plugin list is often a graveyard of things nobody remembers installing. Twenty, thirty, forty active plugins, each adding load time and attack surface, many almost certainly doing nothing visible on the site anymore. Standard WordPress gives you no way to know which ones still matter. A plugin that once powered a custom shortcode on a page deleted two years ago looks exactly the same in the list as one powering your checkout today. Deactivating the wrong one breaks something; leaving all of them active is slow and exposed. A small audit tool changes the situation without requiring blind guesswork. It scans for usage signals: whether a plugin has stored any settings, whether its name appears in post content, and whether its custom post types have any posts. Plugins that fail all three are the first ones to investigate. ## What one build covers - Admin page at Tools > Plugin Usage Audit with on-demand scan - Per-plugin wp_options row count to detect whether settings were ever stored - Per-plugin post content search to detect shortcodes and block name references - Non-built-in custom post type list with post counts for manual cross-reference - 'No signals' flag for plugins with zero evidence in both database checks ## What it does not cover - Hook-based plugins: caching, security, SEO, firewall, redirects will always show zero - Plugins whose option names do not match their folder name - Widget-based plugins not referenced in post content - Definitive safety confirmation: a zero-signal plugin may still be a required dependency - Automated deactivation or deletion — the tool reports only, changes nothing ## The prompt ```text Build a WordPress plugin called Plugin Usage Audit. Plugin Name: Plugin Usage Audit. Description: Scans active plugins for database and content signals to help identify possibly unused ones. Single PHP file. No external dependencies. Register an admin page under the Tools menu using add_management_page. Page title: Plugin Usage Audit. Menu title: Plugin Usage Audit. Capability: manage_options. Slug: plugin-usage-audit. On the page, render a Run Scan button that submits a GET request to the same page with query parameter run=1. Only execute the scan when that parameter is present and current_user_can('manage_options') is true. When the scan runs: 1. Get all installed plugins using get_plugins(). Filter to active plugins using is_plugin_active(). For each active plugin path (e.g. 'woocommerce/woocommerce.php'), derive the slug as the directory name: the portion before the first slash. 2. For each plugin slug, run two wpdb queries: a. Options count: SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE %s, with value '%' . $wpdb->esc_like($slug) . '%'. b. Post count: SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_content LIKE %s, with value '%' . $wpdb->esc_like($slug) . '%'. 3. Build an array of result rows. Sort so that plugins where both counts are zero appear first. 4. Render an HTML table with columns: Plugin Name, Options Matches, Post Content Matches, Signal. In the Signal column, output the text 'No signals' in red (#cc0000) if both counts are zero; otherwise output 'Signals found' in green (#006600). 5. Below the table, add an h2 heading Custom Post Types and a second table listing all post types returned by get_post_types(array('_builtin' => false), 'objects'). For each, show: Label, Slug, and Published Posts count from wp_count_posts($post_type->name)->publish. 6. Above the main table, output a standard WordPress admin notice with class notice notice-warning: 'This scan cannot detect hook-based plugins such as caching, security, firewall, SEO, or redirect plugins. Those will always show zero signals. Use this as a starting point, not a final verdict.' Apply the standard WordPress admin table classes wp-list-table widefat fixed striped to both tables. No external CSS or JavaScript. ``` ## Why plugin lists grow unchecked Most WordPress sites accumulate plugins the same way: a developer installs something to solve a one-off problem, the problem goes away, the plugin stays. A migration from another platform pulls in compatibility shims that were only needed for a month. A client requests a feature, the agency installs a plugin, the feature gets removed from the page, the plugin stays active. Nobody tracks this intentionally. There is no built-in audit trail. The plugin list shows name, version, and status, nothing about whether the plugin has touched a post, registered a custom post type with actual content, or stored any settings suggesting someone configured it. The result on an inherited site is a stack of uncertainty. The safe move is to leave everything active, which compounds over time: each additional plugin is a potential conflict, a security surface, and a performance drain. ## What the audit tool checks The tool adds an admin page at Tools > Plugin Usage Audit. Click the Run Scan button and it queries the database for three signals per active plugin. The first signal is the options count: how many rows in wp_options contain the plugin's folder name. Most plugins that have been configured or used on a live site write at least one option row. A plugin with zero matching rows has probably never been set up. The second signal is the post content count: how many published posts contain the plugin's folder name in their content. This catches shortcodes, block names, and custom HTML that follows the plugin's naming convention. It is not exhaustive, but a plugin whose shortcodes appear across dozens of posts is not unused. Below the main table, a separate section lists all non-built-in custom post types alongside their post counts. Cross-reference this with the plugins you know register CPTs: if a plugin registers a CPT and that CPT has zero posts, it has done no content work on this site. - Tools > Plugin Usage Audit admin page with on-demand scan - Per-plugin: count of wp_options rows matching the plugin folder name - Per-plugin: count of published posts containing the plugin folder name - Global: all non-built-in custom post types with post counts for manual cross-reference - 'No signals' flag for plugins with zero evidence in either database check ## What the tool cannot see The scan has a hard limit: it cannot detect hook-based plugins. Caching plugins, security firewalls, login protection tools, SEO plugins, redirect managers, and analytics integrations all work by hooking into WordPress at runtime. They do not store shortcodes in posts and may not use option names that match their folder name. All of them will show 'No signals', and none of them are safe to deactivate just because the tool cannot find traces. The option name search is also approximate. It looks for the plugin folder name as a substring of option_name values. A plugin with a very short or generic folder name will produce false positives; a plugin that prefixes its options with something unrelated to its folder name will produce a false negative. Use the output as a shortlist, not a verdict. If a plugin shows zero signals and you have no memory of installing it or knowing what it does, that is the right time to read its description, check the last time it touched anything, and test deactivation on a staging copy. ## Extending the audit The most useful addition is a widget check: query the widget configuration stored in wp_options under 'sidebars_widgets' and 'widget_*' keys, then cross-reference which plugins those widget classes belong to. Ask Steem to add a Widget Usage section that shows active widgets and whether the plugin providing each one is installed. For multisite installs, the scan needs to run across all sites in the network, not just the current one. Ask Steem to add a network scan mode that iterates all blogs using get_sites() and aggregates signals across the whole install. If you want a record over time, ask Steem to add CSV export so you can compare a scan from today against one from three months ago and track whether the flagged plugins were actually cleaned up. ## Questions ### My caching and security plugins show 'No signals'. Are they unused? No. Caching, firewall, security, and SEO plugins work by hooking into WordPress at runtime. They do not write shortcodes to post content and often do not use option names matching their folder name. The scan will always return zero for these, which is expected behavior. Do not use this result to decide whether to remove them. ### A plugin I know is active shows zero options matches. Why? The check looks for the plugin's folder name as a substring of option_name values in wp_options. If the plugin prefixes its settings with something that does not match the folder name, it will return zero even though the plugin is fully configured. Verify manually via the plugin's own settings page or a database tool like phpMyAdmin. ### Is it safe to deactivate everything flagged as 'No signals'? Not automatically. Deactivate one plugin at a time and verify the site functions correctly after each one. A zero-signal plugin might be a dependency for another plugin, or may work via hooks this scan cannot see. Always test on a staging copy before changing production. ### Is it safe to run the scan on a live site? Yes. The scan is read-only: it queries the database but changes nothing. It only runs when you click the button on the admin page, not on every page load, so there is no impact on visitors. ### A plugin shows signals but I do not recognise it. What should I do? Check the plugin's description and settings page to understand what it does. Look at which posts the content matches appear in. If those posts are live and in use, the plugin is likely still doing a job, even if you did not install it yourself. --- Source: https://steem.dev/blog/wordpress-find-unused-plugins-audit-tool Build this plugin: https://steem.dev/app