On-Page Keyword Density: Audit Copy Without Stuffing
Audit on-page keyword density with a fixed scope and tokenizer, inspect exact matches, remove awkward repetition, and report counts without ranking claims.
Author credentials: William Zhu is cofounder of InfiniSynapse (GitHub @allwefantasy · auto-coder). Desk: shipping SEO Health and the /en/tool/ visibility pages. No personal LinkedIn published. About: team / editorial standards.
Publisher credentials: InfiniSynapse has public profiles on GitHub, YouTube, and X. A 2026 WAIC Future Tech OPC excellence award covers the Agentic Data Infra entry (WAIC; third-party recap: Xinhua / Caohejing). That award does not review this page or SEO Health. Method CLI: infinitegrowth on npm. Archive: recognition and scope notes.

On this page
By William Zhu · Cofounder, InfiniSynapse · Published: 2026-09-08 · Last updated: 2026-09-14 · Last verified: 2026-09-14 · Reviewed by the InfiniSynapse Data Team.
Reviewed by: InfiniSynapse Data Team · method review 2026-09-14. Exact-phrase count on one published
article.md. No 100-token toy string. No ranking band.
Trust / COI: About · Corrections. SEO Health is a commercial product from this team. This page is not a Google ranking-factor review.
TL;DR
The only density we computed is on a file we already publish, not on a 100-token toy string.
Direct answer: Treat on-page keyword density as exact-phrase hits divided by a declared word count. On 2026-09-14 we counted the published
seo-title-checkerarticle.md: exact “seo title checker” appeared 37 times in 3,088 words (~1.20%). “heading structure SEO” appeared once. “image SEO alt text” appeared once. The sample size is one file.
An on-page keyword density slide that imports a 2% teaching fixture as the desk is already mixing two jobs. Arithmetic on a published file is not a ranking band.
Run a robots and noindex check before you count tokens on a blocked path.
What you will learn
- Which file we actually tokenized
- Why 37 / 3,088 is not a target
- Which sibling phrases appeared once
- When a tokenizer change resets the baseline
- Where title and heading siblings live
What we actually counted
Key definition: on-page keyword density on this desk is one published markdown file × one exact phrase × one word-token rule. A percentage counts only when numerator and denominator are printed. A 100-token toy string is not that file.
People open on-page keyword density after a teammate pastes 2.00% from a constructed sample. That sample is not the desk. Start with a file you already publish. Write hits and words, or write “not counted.”
The Google keyword-stuffing policy defines repeated terms used unnaturally. We cite it as a boundary. We did not treat 1.20% as a stuffing verdict.
SEO Health is the deterministic evidence foundation for a file-level token count. After the numerator exists, an InfiniSynapse Server API long-task workspace can stream SSE /api/ai/events over that same archive; the API does not publish a preferred band.
One published file
The file is SEO/Blog/pillar-sh6-on-page/ig501-seo-title-checker/article.md. Body words start at ## TL;DR. on-page keyword density that swaps in a homepage CLI word count (2,928 on 2026-09-14) without saying the corpus changed is inventing a second denominator.
The Google SEO Starter Guide centers useful organization. It does not name an on-page keyword density target.
What we did not tokenize
No competitor corpus. No Search Console query export. No 100-token filler list. on-page keyword density that hides those absences cannot be replayed.
As of 2026 this page is not a customer copy deck.
The arithmetic on disk
User-agent InfiniSynapse-SH67-desk/2026-09-14 for the same-morning HTML checks. The density row itself is local file arithmetic.
| File | Phrase | Hits | Words |
|---|---|---|---|
ig501 article.md | seo title checker | 37 | 3,088 |
| same file | heading structure SEO | 1 | 3,088 |
| same file | image SEO alt text | 1 | 3,088 |
37 / 3,088 ≈ 1.20%. That is arithmetic. on-page keyword density still has no ranking band to publish.
The Python regular expressions page documents the engine we would use to replay the phrase scan. We kept the URL. We did not treat the library as a Google tokenizer. The count still needs the printed integers, not a library badge.
Figure: Every bar is a phrase in one file. None is a ranking target.
Hits versus words
Word tokens follow [A-Za-z0-9]+(?:'[A-Za-z]+)?. Hyphens split. “on-page” is two tokens in the denominator and one hyphenated span in the phrase. on-page keyword density that reports a percentage without both integers cannot be checked.
Unicode text segmentation explains why another language would need another rule. This count is English markdown.
Sibling phrases in the same file
“heading structure SEO” and “image SEO alt text” each appeared once in that article.md. They are not density targets for this page. They show the same scanner can print a 1 as well as a 37. A later on-page keyword density review should keep those rows labeled as other phrases, not as “almost the keyword.”
The Stanford IR book on term frequency is the information-retrieval context for raw counts. It does not convert 1.20% into a Search score.
How to reproduce the count
python3 - <<'PY'
import re, pathlib
p = pathlib.Path("SEO/Blog/pillar-sh6-on-page/ig501-seo-title-checker/article.md")
text = p.read_text(encoding="utf-8")
m = re.search(r"^## TL;DR\s*$", text, re.M)
body = text[m.start():] if m else text
body = re.sub(r"!\[[^\]]*\]\([^)]+\)", "", body)
body = re.sub(r"\[([^\]]+)\]\([^)]+\)", r"\1", body)
body = re.sub(r"`([^`]+)`", r"\1", body)
words = re.findall(r"[A-Za-z0-9]+(?:'[A-Za-z]+)?", body)
hits = len(re.findall(re.escape("seo title checker"), body, re.I))
print({"words": len(words), "hits": hits, "density": round(100 * hits / len(words), 2)})
PY
Expect about 37 hits and about 3,088 words unless that file changed. Store both integers. Do not paste a 2% fixture under this chart. on-page keyword density reproduction stops at the published file until a reviewer counts a different owned corpus and keeps that archive offline.
MDN textContent documents how a browser exposes node text. This desk counted markdown, not a live DOM textContent dump.
CLI boundary on the same morning
seo-health eeat on https://infinisynapse.com/en/editorial-standards printed unauthorized after a page fetch. This density page did not spend that credit either. The command is not a tokenizer. on-page keyword density notes that quote scores[] without a taskId from a logged-in run are fiction.
Package pin infinitegrowth@0.1.1; -V printed 0.1.0. Record both.
A same-morning seo-health check on /en/tool/seo-title-checker exited 0 and reported 2,928 words on the live HTML. That denominator is a different corpus from the 3,088-word markdown body. Mixing them cannot establish one on-page keyword density percentage.
What a later density pass must keep
When someone does count another page, freeze the file or URL, the included regions, the tokenizer, and the exact phrase. Hash the text. Save hits and words before the percentage. Leave “too high” and “too low” unlabeled until a person reads the sentences.
on-page keyword density fails when navigation is added to the denominator without a new baseline.
Scope and tokenizer
Declare whether navigation, footer, code, captions, and alt text enter. The Apache Lucene analysis guide shows how production analyzers differ. Lucene does not define Google’s rules, and it does not prove 1.20% is desirable.
A hyphen rule that splits on-page changes both phrase matching and word count. Publish the regex beside every percentage.
Exact versus variant
Keep exact target and close variants in separate counters. Stemming “title” and “titles” answers another question. on-page keyword density that merges those buckets is no longer the 37-hit method.
The sample size here is one published file. That cannot establish a preferred band, and it does not prove a rewrite improved rankings.
Failure modes that invent a band
2% fixture as the desk. Teaching arithmetic is not a published file.
Live HTML words as the markdown count. 2,928 and 3,088 are different corpora.
Stuffing policy as a percentage. Unnatural repetition is a judgment.
Search Console as a numerator. Queries are not page tokens.
Lucene as Google. A library is not a ranking function.
Unauthorized CLI as a density fail. Login failed. No file was scored as EEAT.
An on-page keyword density memo that skips the printed integers is already late.
How a reviewer should read the log
Start with 37 and 3,088. Confirm the phrase is still “seo title checker.” Confirm the file is still the published title-checker article. Confirm this page still refuses a 2% fixture. Only then count another corpus, if the ticket actually needs one. on-page keyword density that starts from a toy string will contaminate the record with a denominator nobody ships.
Save the file hash before you edit. Editing can change both hits and words. on-page keyword density that “fixes” the percentage first is measuring the edit, not the 2026-09-14 packet.
If the later file shows zero hits, keep the row. Zero is a result. Deleting quiet files inflates the next average.
When the reviewer is done, the folder should contain: the dated integers, the file hash, and a one-page decision. The decision may be “no action,” “remove an awkward repeat,” or “leave the technical name.” on-page keyword density is not required to produce a ranking forecast.
Do not upload a customer manuscript to a public ticket to prove you worked. Redact. Store a hash of the allowed excerpt. on-page keyword density that publishes raw drafts to look empirical is leaking copy, not proving a ratio.
What stays on disk after this desk
Keep the printed 37 / 3,088, the two sibling 1s, and a one-sentence note that no toy string was used. That folder is the 2026-09-14 on-page keyword density packet. If a later teammate adds another file, they go in a dated subfolder with the new hash, not into this chart.
Print the package pin on the same page as the empty-fixture note: infinitegrowth@0.1.1 and -V = 0.1.0. Those strings do not prove copy quality. They prove which CLI we could have used and did not authorize as a density engine.
A reviewer who needs a punch list can still run seo-health check on a public URL they own. Expect on-page lights, not a preferred percent. on-page keyword density does not promote those lights into a stuffing score.
If legal asks whether we “tested keyword density,” the accurate answer is: we counted exact phrases on one published article file and we did not import a 2% fixture.
Store the user-agent InfiniSynapse-SH67-desk/2026-09-14 beside the HTML checks, not beside the file count. Do not silently replace 3,088.
The decision this page supports is narrow: refuse a ranking band until numerator and denominator exist for a named corpus. on-page keyword density does not decide titles, headings, or budgets. Those decisions need the addendum folder.
When the addendum folder is still empty next quarter, republish the same 37 / 3,088 with a new date if you re-counted the same file. Do not backfill a 100-token toy to make the quarter look complete. Empty of fixtures is a legal state for on-page keyword density. A quarter with one dated file count and a still-empty toy-string ban is a complete desk, not an unfinished slide.
Nearby guides
The SEO title checker owns the file we counted. Do not copy that table here.
| Job | Guide |
|---|---|
| Outline ranks on a live page | heading structure SEO |
| Empty decorative alts | image SEO alt text |
| Thin-page disposition | thin content SEO |
The on-page SEO tool hub still owns the broader eight-check story. on-page keyword density stays on the printed-integer job. A later file will have a different pair of integers; store that pair under a new date and leave 37 / 3,088 in the archive. Do not average two files to invent a host-wide percent. The sample size here is one article.md. That draw cannot establish how other slugs were written, and it does not prove a stuffing penalty.
Keep the 2 percent fixture off this desk
Replay the file count. Tokenize another corpus only when you intend to store that hash offline.
Run SEO Health CheckerFrequently Asked Questions
Is 1.20 percent a ranking target?
No. 37 / 3,088 is arithmetic on one file. on-page keyword density still has no official band.
Should headings and alt text enter the denominator?
Only if the declared scope includes them. Report those regions separately when they serve a different job from prose.
Why would two tools disagree?
They may use different tokenizers, variants, boilerplate rules, or live versus source text. Save the method beside on-page keyword density before comparing tools.
Are Search Console queries part of this count?
No. Queries are performance rows. Density counts terms in page text. Do not merge the datasets.
May we publish a preferred percent from this article’s chart?
No. The chart is hits versus words on one file. It cannot establish a ranking band.
Conclusion
Use on-page keyword density when the job is to refuse a ranking band until both integers can be stored. This 2026-09-14 pass recorded 37 hits in 3,088 words on one published file and zero toy strings. Stop when the numerator, the denominator, and the fixture ban remain visible. A bounded file count beats an unsupported density target.
Print numerator and denominator; do not import a 2% teaching fixture as the desk.
William Zhu · Cofounder, InfiniSynapse · GitHub @allwefantasy
Desk-validated SEO Health methods. Corrections: zhuhl@infinisynapse.com · corrections policy.