Every care-plan portfolio carries plugins nobody chose. They arrived with a theme bundle, a developer who left in 2022, or a client who "just needed a quick slider". Across 60 sites that is usually somewhere between 150 and 400 plugin installs you have never consciously approved, and a handful of them stopped being maintained years ago.
The uncomfortable part is that an abandoned plugin is not a visible failure. It keeps working. It just stops getting the patch when someone finds the hole.
Why abandoned is worse than outdated
An outdated plugin has a fix waiting; you click update and the problem is gone. An abandoned plugin has no fix coming, so the only remedies are removal or replacement, and both need a human decision per site.
The scale is not theoretical. In September 2023 Patchstack reported 404 vulnerabilities in 358 plugins to the WordPress.org plugins team, affecting up to 1.6 million active installs. By the end of that August, 289 of those plugins (about 72%) had been closed in the directory rather than patched, because the authors could not be reached or did not respond. The oldest had gone 13 years without an update (WP Tavern, 2 Sep 2023). Closed means the plugin disappears from search and stops getting updates, but it stays installed and active on every site that already has it. Nothing on the client's dashboard changes.
So the question for an agency is not "are my plugins up to date?" It is "how many of my plugins can still be updated?"
What "abandoned" actually means
There is no official status called abandoned, so you need your own definition and you need to apply it consistently. Three signals are cheap to check and correlate well with risk:
- Last updated date. WordPress.org exposes it on every plugin page and through its API. Anything over two years old is a candidate; anything over three is a problem.
- Tested up to. The directory shows "This plugin hasn't been tested with the latest 3 major releases of WordPress" when the author has not bumped the readme. The data comes from the readme, so it is sometimes stale on well-maintained plugins, but on a plugin that also has an old update date it confirms the picture.
- Directory status. A closed or removed plugin returns nothing from the WordPress.org API. This is the one that should wake you up, because it usually means a security report that nobody answered.
Add a fourth, softer signal: a support forum with no author replies for the last 6 to 12 months.
Premium plugins sold outside the directory need a different check: does the vendor still exist, does the licence still renew, and has the changelog on their site moved in the last year. Treat a dead licence the same as a dead directory listing.
The audit, in numbers
Here is how the work breaks down for a 60-site portfolio, assuming an average of 22 plugins per site (call it 12 on a brochure site, 45 on a WooCommerce build; substitute your own numbers). That is roughly 1,320 plugin installs, but the unique list is much shorter because the same 30 or 40 plugins appear everywhere.
| Step | What you do | Time, first pass |
|---|---|---|
| 1. Inventory | Export plugin slug, version, active/inactive and site for every install. From a management dashboard this is a single export; by hand it is 60 logins. | 15 min with a dashboard, 4–5 h by hand |
| 2. De-duplicate | Collapse to unique slugs. 1,320 installs typically become 120–180 unique plugins. | 10 min |
| 3. Check each slug | Last updated, tested-up-to, directory status. The WordPress.org plugin API answers one slug per request; a script does 150 lookups in a couple of minutes. | 30–45 min scripted, a day by hand |
| 4. Classify | Keep / replace / remove, with the number of sites affected next to each. | 1–2 h |
| 5. Act | Remove inactive ones first (zero functional risk), then replace, lowest-traffic sites first. | Depends on the list |
The first pass is a few hours of work if you have an inventory and a day or two if you do not. The second pass, six months later, is an hour, because you only look at what changed.
Inactive plugins count. A plugin that is installed but deactivated still has its PHP files on the server. Most vulnerabilities need the plugin to be active, but not all of them: a file that can be called directly, or an uploader that does not check whether its parent plugin is enabled, is exploitable either way. An inactive abandoned plugin is also the easiest win in the entire audit, because deleting it changes nothing the client can see.
If even one in ten installs on an unmanaged portfolio is inactive (a conservative guess; count your own), 1,320 installs means about 130 deletions you can do without a single conversation.
Replacing without breaking things
Removal is simple. Replacement is where the audit turns into real work, and the order matters.
Start with the plugin that appears on the most sites, because you learn the replacement once and repeat it. Pick a replacement that is maintained (apply the same three signals), does the same job and nothing more, and has a migration path for the data. Form plugins and SEO plugins carry data; sliders and social-share buttons mostly do not.
Then run it as an update, not a project: restore point first, swap the plugin on one low-traffic site, compare screenshots of the pages that used it, wait a week, roll out to the rest in batches of ten. If you already have an update process for client sites, you have a replacement process; the extra step is only the data migration.
Two things not to do: replace a plugin that is doing nothing on a site (remove it), or leave the old one deactivated "just in case" once the replacement is confirmed. That is how the next audit finds it again.
What to tell the client
Most clients have never heard of plugin abandonment and will not care about the vulnerability count. Tell them in their own terms: "We removed 4 plugins that were no longer maintained and replaced 2 with supported ones. Nothing changes on the site. This is the kind of work the care plan exists for." Put the counts in the monthly report; it is some of the most legible maintenance you do, and it is the sort of line item that justifies the plan when the renewal conversation comes around (more on that in the maintenance checklist clients actually pay for).
When the audit turns up a plugin with a known, unpatched vulnerability, do not wait for the next report. Fix it, then tell the client what you fixed. For the question of which vulnerabilities justify a same-day change, a CVE in a plugin is not automatically an emergency covers the triage.
Making it routine
The reason this feels like a big job is that it is done once every two years, when something forces it. Done quarterly it is small, and the numbers tell you how your portfolio is drifting: a growing count of abandoned installs means onboarding is letting things in, a flat count means the process is holding.
Three habits keep the number down. Vet every plugin at onboarding against the same three signals, so you stop importing problems. Keep the inventory live rather than exported, so step 1 is never the expensive step again. Review the unique-plugin list, not the per-site list; 150 rows is a cup of coffee, 1,320 is a weekend.
WPClientHub keeps that live inventory across every connected site and runs vulnerability scanning with plain-English explanations of what each finding means, so the "check each slug" step is already done when you open the dashboard. It does not clean malware or replace plugins for you; the decisions in step 4 are still yours.
Where this leaves you
An abandoned plugin audit is a few hours of scripted lookups and one afternoon of decisions, not a rewrite of your portfolio. Start with the inactive installs, replace the most widespread problem plugin first, and put the counts in the client report so the work is visible. If you would rather have the inventory and the scan results waiting for you instead of building the export, WPClientHub is free for 3 sites, with paid plans from $19/month.