The SEO Plugin That Won Our Benchmark Is One Almost Nobody Installs
How we built the test rig, the six mistakes that would have made the numbers lie, why the winner beat plugins with 100x its install base, and the measured pros and cons of all seven.
In this article 9 sections
We spent a day building a test rig, ran seven WordPress SEO plugins through it one at a time, and got numbers that surprised us in four places. The overall winner was The SEO Framework — a plugin most people have never installed — because it produced near-complete SEO output for roughly a fifth the server cost of the market leaders. All in One SEO lost every cost category it entered. And our own plugin failed a check so basic that bare WordPress passed it.
This post is the process, not just the scoreboard: how the rig was built, the six mistakes that would each have produced confidently wrong results, the winner and exactly why, and an honest pros-and-cons verdict for all seven. If you only want the raw tables, they are in the benchmark itself. If you want to run this yourself, the methodology guide is the checklist version.
Disclosure up front: we build one of the seven. It did not win.
Updated 8 September 2026. The figures here come from a complete re-run of all seven plugins after we shipped fixes to our own. Details of what changed — including two things we got wrong the first time — are in the benchmark post.
Why we did this at all
Every SEO plugin comparison we could find was one of two things: a feature checklist where every mature plugin ticks every box, or a performance claim with no method attached. Neither helps you choose, because the interesting question is not "does it do schema" — they all do schema. The interesting question is what does it cost you, and what does it actually put in the page.
That question only has an answer if you measure. So we measured.
The rig
One WordPress install that nothing else touched:
| Component | Version |
|---|---|
| WordPress | 7.1 |
| PHP | 8.2.27 |
| Database | MySQL 8.0.35 |
| Theme | Twenty Twenty-Five, unmodified |
| Server | PHP built-in server, single-threaded |
| Other plugins | None active, ever |
A single-threaded server sounds like a weakness and is actually the point: nothing interleaves, so run-to-run variance comes from the machine rather than from requests fighting each other. It makes the timings relative rather than production-absolute, which is exactly what a comparison needs. Nobody cares whether Yoast takes 96 ms on our laptop; they care that it costs roughly three times what The SEO Framework costs on the same hardware.
The content corpus was held completely constant — 40 posts with identical body structure, a featured image, one category and two tags each, plus 8 pages, 6 categories, 15 tags and 5 uploaded images. Every plugin rendered the same words. If the corpus moves, you are measuring your content, not the plugin.
The protocol
For every plugin, and for a no-plugin baseline that every number is expressed against:
- Restore the database from one snapshot taken before any SEO plugin existed.
- Activate exactly one SEO plugin.
- Let it finish installing — load the admin a few times so activation routines run, then flush rewrite rules so sitemap and robots routes resolve.
- Warm up with six discarded requests per URL.
- Measure thirteen requests per URL and take the median.
- Read the server cost from inside WordPress, via a must-use plugin that loads before the plugin under test.
- Deactivate, then measure what was left behind.
Then we ran the entire thing a second time and compared the two passes. Every deterministic metric — memory, query counts, byte counts, autoloaded option sizes, asset counts — came back byte-identical. Timing moved about ±10%, which is normal on a laptop, so timings are the mean of both passes and rankings lean on the stable metrics.
Step 1 is the one people skip, and skipping it invalidates everything downstream: without a restore, plugin number four is measured on a database still carrying plugins one through three.
The six mistakes that would have made the numbers lie
This is the part no comparison post publishes, and it is the part that decides whether the numbers mean anything. Every one of these bit us during the build.
1. Rank Math emitted nothing at all
Our first Rank Math run came back looking identical to the baseline: same head bytes, no schema, no meta description. On the naive reading, Rank Math was the lightest plugin in the test by a mile — it added almost no cost because it was doing no work.
Rank Math gates its front-end output behind registration. Until you either connect a Rank Math account or click Skip, it emits nothing. Measuring it in that state would have handed it a fraudulent win.
The fix was to set exactly the two options its own Skip button writes, and to disclose it. This is a general hazard: a plugin that has not finished its setup wizard is not a light plugin, it is an inactive one. Check that every plugin is actually producing output before you believe a single cost number.
2. Peak memory is measured per process, not per request
Our probe recorded memory_get_peak_usage() at shutdown. On a persistent server process, that is the high-water mark since the process started — so after a warm-up loop, every plugin reported the same number, because the peak had already been set by whichever request happened to be heaviest.
The fix is one line, memory_reset_peak_usage(), called at the very top of the probe. Without it, memory looks like a constant and you conclude that no plugin uses memory.
3. Counting URLs on a sitemap index returns zero
Most of these plugins ship a sitemap index — a small file listing other sitemaps. Counting <url> elements in it gives you zero for every plugin that uses one, and 51 for the one that ships a flat file, so The SEO Framework would have looked like the only plugin with a working sitemap.
You have to follow the index into every child. And then AIOSEO taught us the second half of the lesson: it wraps its <loc> values in CDATA, so the obvious regex matches nothing and the plugin appears to have an empty sitemap index. Discovering the sitemap the way a crawler does — reading the Sitemap: line out of robots.txt — also matters, because these plugins do not agree on the filename: /sitemap.xml, /sitemap_index.xml and /sitemaps.xml are all in use.
4. The admin measurements were silently measuring the login page
Our first admin pass reported the dashboard, the plugins screen and the post editor as 5.6 KB each, identical across every plugin. That is not a suspicious result, it is an impossible one — and the cause was that scripting the WordPress login form had failed, so every request returned the login page.
Generating a session directly is far more reliable than driving the form. And you need both cookies: wp-admin validates the auth cookie, not just logged_in. They also have to be regenerated after every database restore, because the restore wipes the session tokens.
The lesson generalises: when a metric comes back identical across every configuration, that is usually a broken measurement, not a finding.
5. We were counting schema as JavaScript
Our inline-script metric showed every plugin adding two to four kilobytes of inline JavaScript to the front end. That looked like a real story about plugin weight. It was not: JSON-LD lives in a <script> tag, and our regex for "inline script without a src" was scooping up every plugin's structured data.
Excluding application/ld+json collapsed the numbers to exactly 3,837 bytes for all eight configurations — the baseline, unchanged. Which produced the single most useful finding in the whole exercise, in the opposite direction from what we expected: no plugin in this test adds any front-end JavaScript or CSS at all. The metric plugin marketing shouts loudest about is a non-issue, and we only learned that by fixing a measurement that was flattering our own narrative.
6. We nearly published something false about Rank Math
Our sitemap pass showed zero image entries for Rank Math, and the tempting write-up was "Rank Math does not support image sitemaps." That would have been wrong and we would have deserved the correction.
Checking its actual settings showed include_images on and include_featured_image off by default. Our corpus uses featured images, so Rank Math shipped no images — on a site whose images sit inline in post content, it would have. The true finding is narrow and much more useful: at default settings, on a site whose images are featured images, Rank Math's sitemap contains no images. Defaults are a finding; capability claims usually are not.
The winner, and why
The SEO Framework 5.1.4 wins overall. It wins or shares seven of the sixteen measured categories, and the specific ones it took are the ones that compound:
- +0 extra database queries. Alone in the field. Every other plugin added between one and twenty-two.
- +8 registered hooks, against +187 for Yoast and +151 for Rank Math. A small integration surface is a small blast radius.
- +8.0 ms of PHP and +2.0 MB of memory — roughly a fifth of Yoast's cost and a seventh of AIOSEO's.
- The lightest admin we measured: a 130.3 KB dashboard against a 129.8 KB baseline, and 77.6 KB of its own assets in the post editor. AIOSEO loads 3.5 MB there; Yoast loads 4.2 MB.
- The only plugin that restored the baseline exactly on deactivation — 49.8 KB of autoloaded options, to the decimal.
And critically, it is not cheap because it does nothing. It emits a meta description, a canonical, 10 Open Graph tags, 5 X tags and a 9-type schema graph in 1,881 bytes. That combination — near-complete output at the lowest cost in the field — is what wins.
Slim SEO ties or beats it on five raw cost metrics and is the better answer if you want the absolute minimum, but its output is thinner (2 X tags, and a third of its sitemap URLs carry no lastmod) and it gives you almost nothing to configure.
Yoast wins the categories The SEO Framework loses: the richest schema graph in the test (12 types) and the most complete sitemap (75 URLs, 40 image entries, lastmod on 74 of 75). It is the most complete plugin here, and it charges the second-highest PHP cost, the largest hook surface, 4.2 MB of editor assets and six permanent database tables for that completeness. That is a coherent trade, not a defect.
Pros and cons, all seven
Every pro and con below is a measurement from this run, not an impression.
The SEO Framework 5.1.4 — 🏆 overall winner
Pros: Cheapest real plugin in the field (+8.0 ms, +2.0 MB). Zero extra queries. Only +8 hooks. Admin and editor almost indistinguishable from no plugin. Emits description, canonical, 10 OG, 5 X tags and 9 schema types. Cleanest deactivation of any plugin — exact baseline restore. No custom database tables — one of only three plugins here that creates none. No extra cron jobs. 2.9 MB shipped.
Cons: Sitemap is a deliberately minimal flat file — 51 URLs, posts and pages only, no image entries and no index, so taxonomy and author archives are not submitted. Automation-over-configuration philosophy means fewer knobs if you want manual control. No AI features by design. Least beginner hand-holding in the group.
Slim SEO 4.10.1 — 🏆 lightest
Pros: Second-cheapest (+10.0 ms). Smallest <head> growth (+1,649 bytes). Only plugin whose autoloaded options came out below baseline (−0.2 KB). Smallest shipped package at 1.4 MB. No custom tables. Adds zero admin menu items. 10-type schema graph and 11 OG tags. Sitemap includes featured images.
Cons: Only 2 X/Twitter tags — thinnest social output here. lastmod missing on 23 of 73 sitemap URLs. Near-zero configuration surface, which is the whole point but also the whole limitation. The only plugin that added an admin notice (9 vs the baseline 8).
Yoast SEO 28.4 — 🏆 most complete output
Pros: Richest schema graph measured (12 types, 3,976 bytes). Most complete sitemap (75 URLs, 40 images, 74 lastmod). Only +3 queries despite its size — its indexables architecture pre-computes work rather than doing it at render time. A decade of real-world testing and the best documentation in the category.
Cons: Second-highest PHP cost (+39.0 ms) and highest memory (+10.5 MB). Largest hook surface in the test (+187). Prints no <meta name="description"> when none is set and no template is configured — a defensible choice, and a surprise if you assumed otherwise. 4.2 MB of its own assets in the post editor, the heaviest single figure we recorded. Creates six custom database tables that survive deactivation. 21 MB shipped. Adds 5 cron jobs.
Rank Math 1.0.278 — 🏆 most complete social tags
Pros: Best social coverage in the field (11 OG + 8 X tags) plus description and canonical. Full lastmod coverage. Genuinely generous free tier. Moderate memory cost (+8.5 MB) for the feature volume.
Cons: Emits nothing until you complete or skip its setup wizard — the single biggest trap in this benchmark. +36.1 ms PHP and +16 queries, up from a wandering 41-50 at the previous version — the only regression we saw from any plugin update during this work. +11.6 KB of autoloaded options, and deactivating it releases almost none of that. Creates six custom tables, four of them ActionScheduler. No featured images in the sitemap at defaults. Sitemap omits tag and author archives (59 URLs vs 74 for core). 24 files and 1.8 MB in the editor. 15.1 MB shipped. Adds 4 cron jobs and 155 hooks.
SEOPress 10.2 — best value pick
Pros: Cheapest of the "big four" (+24.5 ms, +6.5 MB). Only +1 query. Modest autoload growth (+3.6 KB). Only 217 KB of editor assets — a fifth of Rank Math's, a twentieth of Yoast's. Sitemap includes featured images. Restrained admin. Adds no cron jobs. Aggressive pro pricing that agencies notice.
Cons: Outputs no JSON-LD at all at default settings in the free version — the largest single output gap in the test, and a real problem for rich results and for AI answer engines. lastmod missing on 8 of 58 sitemap URLs, and only 58 URLs indexed. Deactivating releases exactly none of its autoloaded options. Uses /sitemaps.xml, which trips up anyone checking the conventional filename.
Hydrogen SEO 0.0.18 — ours
Pros: Third-cheapest overall (+12.9 ms, +4.5 MB) despite full feature coverage. Second-fewest queries (+1 on a fresh install, +0 once settings have been saved). Near-zero autoloaded options (+0.4 KB, second only to Slim SEO). Best schema efficiency in the test — 10 types in 2,071 bytes, roughly half Yoast's byte cost for a comparable graph. Full lastmod coverage — 72 of 72 sitemap URLs, and one of only two plugins with both complete lastmod and featured images. Lightest admin dashboard of any feature-complete plugin (131.1 KB against a 129.5 KB baseline). Only 2 asset files in the editor. No custom database tables. Every non-AI feature works with no account. Ships an actual SEO agent, which nothing else here attempts.
Cons: Still in Beta, with none of the years of field testing the established plugins have. Third on memory (+4.5 MB) because it loads all of its modules on every request, including admin-only ones — the largest fix still outstanding. 700 KB of editor assets: far lighter than Yoast, AIOSEO or Rank Math, heavier than The SEO Framework, Slim SEO and SEOPress, because the editor UI is a React bundle. 4.6 MB shipped, third-smallest but still three times Slim SEO. Adds one cron job. AI features require a free account. And in 0.0.14 it emitted no canonical tag at all — fixed in 0.0.15, re-verified above, and discussed below rather than buried.
All in One SEO 5.0.1.1 — the expensive one
Pros: Genuinely approachable — guided setup, clear screens, sensible defaults. Full lastmod coverage across 73 sitemap URLs. Solid 8-type schema graph. A large, actively maintained product with a broad plugin ecosystem.
Cons: Lost every cost category it entered. Highest PHP cost (+53.5 ms). Highest memory (+14.5 MB). +22 database queries. Largest <head> growth (+6,668 bytes). Nine custom database tables — more than any other plugin here. A 511 KB admin dashboard, roughly four times bare WordPress, and 130 of its own files in the post editor. Largest package at 24.4 MB. Deactivating it releases nothing at all — all 14.6 KB of its autoloaded options keep loading on every request. Thinnest social output of the majors (6 OG, 3 X). No image entries in the free sitemap.
The part where our own plugin failed
The benchmark's most valuable output was not a ranking. It was that Hydrogen SEO 0.0.14 shipped no rel="canonical" on any post, page, category, tag or author archive — while also suppressing the one WordPress core would have printed. Bare WordPress handled canonicals better than our plugin did.
The cause was more interesting than the symptom. Canonical output was opt-in per context handler, and only the homepage had ever been wired up. Any context nobody remembered lost the tag silently, and nothing failed loudly enough to notice. That is a design that re-breaks itself, so the fix was not to add the three missing calls: canonical output now lives in one place that covers every context, honours a per-page override, points paged archives at themselves instead of page one, and deliberately leaves search results and 404s alone.
It shipped in 0.0.15, verified across eleven cases, with the plugin's full suite and static analysis clean.
Profiling why we placed third rather than first then turned up a second piece of waste. All seven of our extra queries came from reading our own settings one key at a time — and on a site that had never saved a settings screen, none of those rows existed, so each read cost a query that found nothing. WordPress caches a miss only for the current request unless a persistent object cache is installed, so every page view paid seven round-trips to learn the keys were still absent. Priming them in one query took that to +1 on a fresh install and +0 on a configured site, at a cost of 72 bytes of autoloaded options. The same pass found src/ — the pre-build TypeScript — shipping alongside the compiled output, and removed about 1 MB from every install and update.
We published the canonical defect in the benchmark post before any of it was fixed, and the account of it is still there now that the row reads ✅. The tables have since been re-measured on a rebuilt rig — every plugin, not just ours — because comparing our new numbers against everyone else's old ones would have been worthless.
If you take one thing from this post, take that: we ran our own product through the same rig as everyone else's and it lost a category to bare WordPress. That is what benchmarking is for, and it is the reason the other numbers here are worth reading.
What this test does not tell you
- Absolute timings do not transfer. A single-threaded server on a laptop is not your production host. The ratios transfer; the milliseconds do not.
- One corpus, one theme. Forty posts on Twenty Twenty-Five. A WooCommerce store with 40,000 products would rank these differently, particularly Yoast, whose indexables architecture exists precisely for that scale.
- Defaults only. Every plugin was measured at its own defaults. Most of these gaps — Rank Math's sitemap images, SEOPress's schema — are settings away from closing, and closing them costs something we did not measure.
- No pro tiers. Free versions only.
- Nothing subjective. Interface quality, documentation, support responsiveness and how much you like the admin are real reasons to choose a plugin, and none of them appear in a table.
Run it yourself
Nothing here needs our infrastructure: one scratch site, a database restore between runs, a must-use plugin that reads memory, queries and wall time, and the patience to follow a sitemap index into its children. The methodology guide has the probe source, the exact SQL for autoloaded options, the cookie-generation snippet, and every trap above written as a checklist.
If a plugin's numbers disagree with ours, we would rather know. And if you want to hold Hydrogen SEO to exactly this standard, the core is free with no account required — install it, run the rig, and check the canonical output first.