SEO Health Scores: How to Build One You Can Trust
A trustworthy SEO health score is a weighted average of individual checks, where every check maps to a specific defect a person can fix, and every input can be traced back to the API call that produced it. Most seo analysis tools fail that second half: they show you an 82 out of 100 without telling you which checks ran, how each one was weighted, or which pages were sampled, which makes the number impossible to argue with and impossible to act on.
This guide covers how to build a score you can defend in a meeting. It walks through what belongs in the model, how to weight checks so severity and prevalence do not cancel each other out, why aggregating a site down to one integer destroys the information you actually need, and how to keep the score stable enough that a movement means something happened rather than that the sampler picked different pages this week.
What does an SEO health score actually measure?
Nothing, on its own. A score is a summary statistic over a set of checks, and it inherits all of its meaning from that set. Two tools can both report 74 for the same site while measuring almost disjoint things: one might be running 40 on-page checks against 100 crawled pages, another might be blending a Lighthouse performance score with a link-profile estimate and a keyword-coverage guess.
So the first question is never "what is my score" but "what is in the score." Most seo analysis tools will tell you if you ask, and the ones that will not have told you something important. A defensible model has four layers, and each answers a different question.
Crawlability and indexation. Can a search engine reach the page and is it allowed to keep it? This covers robots.txt directives, meta robots and X-Robots-Tag headers, canonical tags that point somewhere sane, HTTP status codes, redirect chains, sitemap presence and accuracy, and whether the URLs in the sitemap actually return 200. These checks are binary and high severity. A noindex tag left on a template after a staging deploy is not a 3 point deduction, it is an outage.
On-page structure. Does the page state what it is about in the places parsers read first? Title tag presence, length, and uniqueness across the site. A single H1. Heading order that does not skip levels. Meta description presence. Image alt text coverage. Internal link count and anchor variety. Structured data that validates against the schema type it claims. These checks are gradient rather than binary, and they are where most fix lists get long.
Performance, measured twice. Lab performance from Lighthouse tells you what a page does under controlled conditions. Field performance from the Chrome UX Report tells you what real visitors experienced. These disagree constantly, and the disagreement is informative rather than a bug. More on this below.
Demand-side reality. Search Console impressions, clicks, average position, and coverage state. This is the only layer that tells you whether any of the other three matter for the pages people actually reach. A perfect on-page score on a page with zero impressions in 90 days is a maintenance cost, not a win.
If your model is missing a layer, the score is not wrong so much as narrow, and you should name the narrowness in the label. "On-page score" is honest. "SEO health" implies you looked at everything.
Why do single numbers mislead?
Because averaging collapses two dimensions that behave completely differently: how bad a problem is, and how much of the site has it.
Consider two sites. Site A has one page with a noindex tag, and that page is the pricing page. Site B has 400 blog posts missing meta descriptions. Under a naive percentage-of-checks-passed model, Site A scores near 100 and Site B scores near 60. The real situation is reversed: Site A has a revenue page invisible to search, Site B has a cosmetic issue that Google routinely works around by generating its own snippets.
Three specific failure modes come out of naive averaging.
Severity dilution. A catastrophic single failure gets averaged against hundreds of passing checks and disappears into the rounding. Any model that can hide a noindex on a money page inside a 97 is broken by design.
Prevalence inflation. A trivial check applied to every page becomes the dominant term simply because it fires often. Alt text is the classic case. It matters, it is worth fixing, and it should never be able to drag a score more than a few points because it repeats 2,000 times.
Non-comparability across sites. A 10 page documentation site and a 50,000 page marketplace cannot share a scale. The marketplace will always have more absolute defects and the doc site will always look pristine, which tells you about site size rather than site quality. Scores are only comparable to themselves over time, and even that requires holding the check set and the sample constant.
The practical answer is not to abandon the score. Executives need one number and there is nothing wrong with that. The answer is to make the number a weighted, capped, severity-aware rollup, and to always ship it attached to the fix list that generated it. A score without its fix list is a rumor.
How should you weight the checks?
Start from consequence. The weight of a check should reflect what happens to organic traffic if the check fails, not how easy the check was to write.
A workable structure separates weight into two multiplied terms: category weight, which is how much a whole class of problems can move the score, and severity weight, which is how much a single instance costs inside that class. Then cap each category so no single class can dominate no matter how many instances it has.
| Category | Category weight | Severity of one instance | Cap | Rationale |
|---|---|---|---|---|
| Indexation blockers | 30 | Critical, 30 points each | 30 | One blocked key page removes the page from search entirely |
| Broken responses and redirect loops | 15 | High, 5 points each | 15 | Direct loss of crawl budget and link equity |
| Canonical and duplicate signals | 12 | High, 4 points each | 12 | Consolidates or splits ranking signals across URLs |
| Core Web Vitals, field data | 12 | Medium, scaled to p75 distance | 12 | Confirmed ranking input and a real user experience cost |
| Titles and H1s | 10 | Medium, 2 points each | 10 | Primary relevance signal, cheap to fix |
| Internal linking and orphan pages | 8 | Medium, 2 points each | 8 | Determines discovery and importance distribution |
| Structured data validity | 5 | Low, 1 point each | 5 | Affects rich result eligibility, not core ranking |
| Meta descriptions | 4 | Low, 0.5 points each | 4 | Influences click-through rate, often rewritten by Google |
| Image alt coverage | 4 | Low, 0.25 points each | 4 | Accessibility and image search, rarely a ranking event |
The caps are the important part. Without them, a site with 3,000 images and no alt text loses 750 points from a 100 point scale, so you clamp, and the moment you clamp you have admitted that the underlying model was additive when it should have been proportional. Cap explicitly from the start instead.
Two refinements make this model considerably more honest.
Page importance weighting. Not all pages deserve equal vote. Weight each page by a blend of its Search Console impressions over the trailing 28 days and its internal link depth from the homepage. A defect on a page with 12,000 impressions should cost more than the same defect on a page with 4. This single change is what stops a score from being dominated by the long tail of archive pages nobody visits.
Confidence weighting. Some checks are certain, such as an HTTP status code. Some are inferred, such as whether two pages are duplicates. Multiply inferred checks by a confidence factor below 1 and expose that factor in the detail view. A user who sees "duplicate content, 0.6 confidence" trusts the tool more than one who sees an unqualified assertion that turns out to be wrong.
For the underlying crawl mechanics that feed all of this, the choices in what to look for in an SEO audit tool determine what your model is even able to weigh. A tool that cannot render JavaScript cannot tell you whether your headings exist.
What do seo analysis tools get wrong about scoring?
Four things, consistently.
They hide the check list. If you cannot enumerate every check and its weight, the score is a black box, and a black box cannot be improved against. The first thing to ask any vendor is for the full list. If the answer is that the methodology is proprietary, the score is a marketing asset rather than a diagnostic.
They mix lab and field data without labeling it. A performance number that silently switches between Lighthouse simulation and real user data is worse than either one alone, because a change in the number no longer has a single possible cause.
They resample without saying so. Many crawlers sample a subset of pages on each run. If the sample is not held constant, a five point drop can mean the crawler happened to pick five bad pages this time. Deterministic sampling, using a stable hash of the URL, fixes this and costs nothing to implement.
They score things they cannot measure. Domain authority proxies, keyword difficulty estimates, and content quality guesses get folded into health scores where they do not belong. Those are modeled numbers from third party indexes, not observations of your site. Keep them out of a health score, or put them in a separate panel with a different name.
The better seo analysis tools distinguish themselves by refusing to guess. They report exactly what the API said, they show the collection timestamp, and they mark anything inferred as inferred.
How do you separate lab data from field data?
Treat them as answers to different questions and never average them together.
Lighthouse, delivered through the PageSpeed Insights API, runs a simulated load on emulated hardware with a throttled network. It is reproducible, it isolates the effect of a code change, and it will run on a page that has zero traffic. That last property is why it is the only option for a new page or a staging environment. It is also why the score bounces: simulated throttling amplifies small variations, and running the same URL twice in a row can produce meaningfully different numbers.
The Chrome UX Report reflects what real Chrome users experienced, aggregated at the 75th percentile over a trailing 28 day window. It is the data that matches how Core Web Vitals are actually assessed. It cannot be gamed by testing on a fast laptop. Its downsides are that it needs enough traffic to report, it lags changes by up to 28 days as the window rolls, and it often reports only at the origin level rather than per URL for smaller sites.
The correct handling in a scoring model:
- Use field data as the graded input when it exists. Score against the published thresholds: 2.5 seconds for Largest Contentful Paint, 200 milliseconds for Interaction to Next Paint, 0.1 for Cumulative Layout Shift, each at the 75th percentile.
- Fall back to lab data when there is no field data, and mark the result as provisional in the detail view so nobody treats a lab number as a user outcome.
- Never blend them into a single performance figure. Show both, side by side, with the collection window on each.
- Expect them to diverge. A page can score 95 in Lighthouse and fail field LCP because real users arrive on mid-range Android phones over mobile networks with a third party tag manager loading first.
The gap between the two is itself a useful signal. A large gap usually points at something the lab environment does not reproduce: geography, device mix, third party scripts that load conditionally, or a cold cache on first visit. Practical detail on collection cadence and alert thresholds lives in monitoring Core Web Vitals over time, and the request shapes and quota behavior are covered in the PageSpeed Insights API guide.
How do you make a score that moves a team to act?
A score changes behavior only when it converts into a queue of tasks with owners. That means the score needs three properties it usually lacks.
Every deduction resolves to a URL and a line. "Titles" is not a task. "These 14 URLs have titles over 60 characters, here they are, here is the current title and a suggested replacement" is a task. If a deduction cannot name the artifact to change, drop the check.
Deductions carry an effort estimate. A template fix that repairs 400 pages at once is a different kind of work than 400 individual edits. Group the fix list by the change that resolves it, not by the check that found it. One template change usually explains most of a site's deficit.
The score has a decomposition view. When it drops four points, the interface should answer "because of what" in one click. Category deltas since the last run, the specific instances that appeared or disappeared, and the run timestamps. Without this, every score movement generates a meeting instead of a ticket.
There is a second-order effect worth planning for. Any score that gets reported upward will eventually be optimized directly, which is fine when the checks are real defects and corrosive when they are not. This is the strongest practical argument for keeping soft or inferred metrics out of the composite. If someone can raise the number by stuffing keywords into headings, they eventually will, and the score stops describing the site.
Once the fix list is reliable, the repetitive parts of the loop are worth handing off. Re-crawling on a schedule, comparing to the last run, and opening tickets for new regressions is mechanical work, and the patterns in technical SEO automation cover how to wire that without a human running exports every Monday.
How does Skopx compute Site Health?
Skopx Site Health combines four sources and reports a 0 to 100 score with the fix list attached rather than a bare number.
Lighthouse scores come from the Google PageSpeed Insights API, so the lab measurements are the same ones you would get running PSI by hand. Real user Core Web Vitals come from CrUX, kept separate from the lab figures rather than averaged into them. Search Console performance data supplies the demand side: impressions, clicks, and position, which is what page importance weighting needs to be anything more than a guess. On top of those three, an in-house on-page SEO audit runs the crawlability, structure, and metadata checks and produces the fix list that the score summarizes.
The design principle is that the score is a view over the fix list rather than the other way around. Every deduction points at a URL and a specific change. Nothing in the composite is a modeled third party authority estimate.
Site Health sits alongside the rest of the Skopx platform, which connects nearly 1,000 business tools, so an audit finding can flow into wherever the work actually gets tracked without a manual export. Skopx also runs AI Visibility, which generates buyer-intent prompts from your site, sends them through search-grounded AI, and reports share of voice along with the citation gaps where a competitor is named instead of you. That is a separate score with a separate methodology, and it deliberately stays separate: mixing traditional crawl health with AI citation share into a single number would reproduce exactly the problem this article is about. If AI surfaces matter to your reporting, how to measure AI visibility describes what that measurement involves.
Pricing is $5 per month for Solo and $16 per seat per month for Team, and AI usage runs on the included allowance or on your own key with zero markup. On security, Skopx has SOC 2 controls in place.
How do you audit your own scoring model?
Run these five tests before you trust a score enough to report it.
The reproducibility test. Run the audit twice within an hour with no site changes. Field data should be identical, since CrUX updates daily at most. Lab data will vary, and you should know the size of that variation so you can set a movement threshold beneath which nobody investigates. If the on-page portion varies at all between identical runs, your sampling is not deterministic.
The injected defect test. Add a known problem to a staging environment: a noindex tag on an important page, a redirect loop, a duplicated title. Confirm the score moves by the amount your weight table says it should. If it moves by a different amount, the implementation does not match the documented model, and the documentation is what people believe.
The scale invariance test. Score a 20 page site and a 5,000 page site with proportionally identical defect rates. The scores should land close together. If the large site scores far lower purely on volume, prevalence is leaking into severity.
The importance test. Move a defect from a zero-traffic archive page to your highest-impression page. The score should drop further. If it does not, page importance weighting is not actually wired in, whatever the settings page says.
The explanation test. Take any single point of deduction and trace it to the raw API response that produced it. If any step in that chain is unavailable in the interface, that portion of the score is unfalsifiable and should be labeled as such.
A model that passes all five is one you can put in front of a skeptical engineer. Most seo analysis tools cannot pass the second and fourth, and running the injected defect test against a vendor trial takes about an hour. For the manual pass that catches what automated checks structurally cannot, such as whether the page answers the query it ranks for, work through a website audit checklist alongside the automated run, and pull the demand-side inputs with the methods in the Search Console API guide.
Frequently Asked Questions
What is a good SEO health score?
There is no cross-tool answer, because the number is defined by the check set behind it, and no two vendors use the same one. Within a single tool, the useful reading is the trend and the composition. A site sitting at 68 with zero indexation blockers is in better shape than one at 88 with a noindex on its highest-converting page, which is precisely why the category breakdown matters more than the headline figure. Judge the score against your own previous runs, never against a competitor's screenshot from a different tool.
Does Google use an SEO health score?
No. Google does not publish or use any composite health score, and no third party has access to one. Google does confirm specific ranking inputs, including Core Web Vitals and mobile usability, and it exposes indexing state through Search Console. A health score is a convenience layer that a tool builds on top of those observable signals. Any vendor implying their score is what Google sees is describing something that does not exist.
How often should the score be recalculated?
Match the cadence to the data source. CrUX field data updates daily, with a 28 day trailing window, so recomputing field metrics more than once a day produces nothing new. On-page crawls make sense weekly for most sites, or on deploy for teams that ship often, since template changes are the main cause of sudden multi-page regressions. Search Console data finalizes over two to three days, so treat the most recent 72 hours as provisional. Continuous recalculation mostly generates noise and alert fatigue.
Should Core Web Vitals be part of the score at all?
Yes, weighted modestly, and using field data rather than lab data whenever field data exists. Core Web Vitals are a confirmed ranking input and a genuine user experience measure, so excluding them leaves a real gap. Weighting them heavily is the more common error: a page that loads instantly and does not answer the query will not rank, and passing all three thresholds is closer to removing a penalty than earning a boost. Around 10 to 15 percent of the composite is a defensible range.
Why did my score change when I did not change the site?
Usually one of four causes. The CrUX window rolled and a slow week aged out or aged in. The crawler sampled a different set of pages, which points at non-deterministic sampling that should be fixed. Search Console data for recent days finalized and shifted the importance weights. Or the tool changed its own methodology, which good vendors version and announce. A score that moves without an attributable cause is a score you cannot report, so the decomposition view is not a nice-to-have.
Can one score cover both traditional search and AI answers?
It should not. Crawl health and AI citation share have different inputs, different update frequencies, and different fix actions, so averaging them produces a number where a drop has no single interpretation. Keep them as separate scores with separate methodologies, reported side by side. AI visibility measurement in particular depends on prompt selection and grounded model responses rather than on crawling your own pages, which makes it a fundamentally different measurement rather than another category to fold in.
Skopx Team
The Skopx engineering and product team