Skip to content
bizurk
← ALL WRITING

2026-08-19 / 18 MIN READ

Topical cluster link topology that earns authority signal

A hub-and-spoke internal link topology for topical clusters: link counts, lateral ratios, anchor diversity, and why site-wide nav links do not count.

The first 60 articles I shipped on this site had a problem. Every one was technically correct. The cluster shape was right, the hub existed, the spokes existed. None of them ranked yet, because the links between them were sloppy. The topology was fine on paper. The implementation was a graph where any of those articles could have been the hub and you would not have known the difference. Two weekends and one audit script later, the cluster started moving.

This walkthrough is the topology I now use, end to end, and the link-count math behind it. It assumes you have a cluster but the internal linking inside it is either ad-hoc or following a template that does not actually reinforce topical authority. By the end you should know exactly how many links each article in the cluster carries, where each one points, and which links you should NOT add even though you might be tempted to.

Prerequisites for this to work

A few things have to be in place before topology work pays off.

You need a hub article that exists at a stable URL. The hub is the broad-topic pillar piece that the rest of the cluster reinforces. On this site, the pillar guide for programmatic SEO at DTC scale is the hub for the cluster you are reading this article in. Stable means the URL is not going to migrate, the slug is not going to change, and the page is not going to get redirected mid-program.

You need 8-25 spoke articles in the cluster, each targeting a closely related query. Fewer than 8 is not really a cluster yet, it is a few related posts. More than 25 starts to fight itself for internal-link budget without a more sophisticated topology than this. The sweet spot in my experience is 12-20.

You need a registry or a simple JSON map of which slug links where. The site you are reading uses an _registry.json file that records every article's outbound links and every anchor phrase claimed against every target. Concurrent writer processes update the file with a sha256 optimistic-retry pattern so they do not stomp each other. You do not need that level of plumbing on day one. A spreadsheet with one row per article and one column per cluster sibling works fine until you outgrow it.

You need to be willing to NOT put the hub in your site-wide navigation. This is the counter-intuitive prerequisite. I will get to why in step 5.

Open a blank document. Put the hub in the middle. Draw a circle of spokes around it. Connect every spoke to the hub with a line that points to the hub. That is the first half of the topology.

Now connect each spoke to 3-5 sibling spokes. Not all of them. 3-5. Pick siblings that are semantically close, the ones a reader who finished this spoke would actually want to read next. The links go in both directions: spoke A links to spoke B, spoke B links to spoke A, but A does not link to C just because B does.

Last, the hub links out to every spoke in the cluster. The hub is the only article that maintains a link to every other article. The spokes are constrained.

The link-count math for a 20-spoke cluster looks like this. The hub has 20 outbound links to spokes. Each of the 20 spokes has 1 link back to the hub plus 3-5 lateral sibling links, call it 4 on average. That is 20 spokes times 5 = 100 outbound links from spokes, of which 20 point at the hub and 80 point laterally. The hub receives 20 inbound links from spokes. Every spoke receives roughly 8 inbound lateral links from siblings on average (because lateral links are bidirectional and 4 outbound times 20 spokes / 20 spokes = 8 inbound). The hub also receives 1 link from the cluster index page and any links from outside the cluster.

That math is the first thing the audit script enforces. It walks every spoke, counts the outbound links, separates them into hub-pointing and lateral-pointing, and flags spokes that are off the target distribution. The shape it is enforcing: 1 link to hub, 3-5 links lateral, 0 links across cluster boundaries except via the hub bridge described in step 4.

The reason this exact shape matters is that Google's internal-linking signal, as best anyone has reverse-engineered it, weighs a link by how thematically connected the source and target are. A cluster where every spoke connects to the hub plus a small set of close siblings is a dense, thematically-coherent subgraph. A cluster where every spoke links to every other spoke is a complete graph that looks like a link farm and gets discounted. The sparseness is doing real work.

Tight macro of a single jagged ice shard with crystalline fractures, abstract close composition.
// the shard close in · fractures and edges

Step 2: pick lateral siblings by semantic distance, not by tag

Tags are a proxy for relevance, not a measurement. Two articles that share a tag might be addressing completely different facets of a topic. The naive approach is to pick lateral siblings by shared tag, which works well enough for tiny clusters and falls apart at scale.

The approach I used on an SEO intelligence build was to compute a vector embedding for every article (title, description, and the first 1,000 words of body), store the embeddings in a Postgres table with the pgvector extension, and pick lateral siblings by nearest-neighbor cosine distance. For each spoke I queried the top-10 most similar siblings inside the same cluster, dropped the spoke itself, and surfaced the top 4-5 to the writer. The writer made the final call, but the candidates were ranked by actual semantic similarity.

The cheap version is the same algorithm done by hand. Read the headlines of every spoke in the cluster. For each spoke, pick the 4-5 spokes a reader who finished that article would most plausibly want next. Log the choice in your registry so the audit can verify it later. This works fine for clusters under about 20 spokes; past that the human gets sloppy and the embedding approach pays off.

What you are looking for, either way, is semantic adjacency. The lateral link from "Step 1: draw the topology" to "Step 2: pick lateral siblings" is high-relevance because they are sequential steps. The lateral link from "Step 1" to "Common mistakes in cluster architecture" is medium relevance, the topics touch but they are different functional pieces. The lateral link from "Step 1" to "Programmatic SEO without HCU risk" is low relevance even though they are in the same cluster. Pick the high-relevance ones.

Wide atmospheric interior of an icy cave at dusk with diffuse pink ambient light across the space.
// the cave at dusk · pink ambient in the air

Once you have the spoke's lateral siblings selected, you also need to place the hub link itself. Position matters here for two reasons.

The first reason is link equity flow. Internal-linking research suggests that links higher in the body carry more weight, partly because the source's first paragraphs are weighted more heavily for topical signal, and partly because crawlers see them sooner. A hub link in the closing paragraph of a 2,400-word spoke is worth less than a hub link in the second or third paragraph of the same spoke.

The second reason is reader behavior. Most readers do not finish the article. If the hub link is in the last paragraph, very few readers see it. If it is in the third paragraph, most readers see it. The link does navigation work for the reader and signal work for the crawler. Both want it early.

The anchor text matters too. Avoid exact-match keyword stuffing on the hub link. The hub for this cluster is "programmatic SEO at DTC scale" and the keyword phrase is "programmatic SEO DTC". You do not want every spoke pointing at the hub with the exact anchor "programmatic SEO DTC" because that pattern is a textbook over-optimization signal. You want anchor diversity.

The target I use is 0.85+ unique anchor phrases across the cluster. That means out of 20 spokes pointing at the hub, at least 17 of them use a unique anchor phrase. Phrases like "the programmatic SEO pillar I work from", "the broader cluster on programmatic content scale", "the hub article that frames this whole program", "the pillar guide" all point to the same hub but with different surface text. The audit script tracks this in the registry's anchorsClaimed map, which records every anchor phrase used to point at every target slug. New articles consult this map and pick a phrase that does not collide.

Step 4: constrain laterals to in-cluster only

The lateral links on each spoke stay inside the cluster. A spoke in the programmatic-seo-content-ops cluster links laterally to other spokes in that same cluster. It does NOT link laterally to a spoke in the dtc-shopify-infrastructure cluster, even if the topics touch.

Cross-cluster links exist, but they go through the hubs. The pattern is: spoke -> own hub -> adjacent hub -> adjacent spoke. The reader who wants to traverse from a programmatic-SEO spoke to a Shopify-architecture spoke goes via the two hubs, not via a direct spoke-to-spoke shortcut.

This sounds restrictive. It is restrictive on purpose. The reason is that lateral spoke-to-spoke links across clusters dilute the topical concentration. If 80% of your inbound lateral links are from the same cluster and 20% are from outside, the cluster looks topically focused. If 50% are from outside, the cluster looks like a generic-topic blog rather than a topical-authority site. Google's reranking treats those very differently.

The hub-to-hub bridges are where adjacent-cluster connection happens. The programmatic-SEO hub links to the analytics hub. The analytics hub links to the Shopify hub. Hubs are allowed to talk to each other freely. Spokes are not.

The exception, and there is always one, is when an article inside cluster A genuinely is about cluster B's topic. In that case the article belongs in cluster B, and you should move it. The fact that you are tempted to add a cross-cluster lateral link is usually a sign the article is in the wrong cluster.

Close fragment of split ice with a glowing interior, crystalline edges catching cold light.
// fragment of ice · glow inside the split

Step 5: keep the hub out of the site-wide nav

This is the counter-intuitive step that surprises most operators.

Your site-wide navigation, the menu that appears on every page of your site, is worth almost nothing for topical authority signal. Every page on your site links to the items in the nav. Crawlers see those links as boilerplate. The internal-linking signal Google's ranking model uses heavily discounts boilerplate links.

What this means in practice: if you put your hub article in your site-wide nav, every page on your site links to the hub, but those links are worth approximately zero each toward the cluster's topical authority. The 200 spokes-and-other-pages on your site each "linking" to the hub does not move the needle. The 20 in-cluster spoke links DO move the needle, because they are body links from thematically-related pages.

Where the hub link DOES belong:

The cluster's index or topic page. On this site that is /writing/topics/programmatic-seo-content-ops. The topic page lists every article in the cluster and lives at a URL Google can crawl. It is fine for the topic page to link to the hub.

The body of every spoke article in the cluster. This is the 1-link-per-spoke we already established in step 1.

The breadcrumbs on each spoke page. Breadcrumbs that read Writing > Programmatic SEO > [spoke title] do NOT need to link the cluster name to the hub explicitly, but they should at minimum exist so that the URL hierarchy is visible.

The sitemap.xml. Just present, just visible to crawlers, not weighted as content.

What the hub does NOT belong in:

The header nav. The footer link grid. A "popular posts" sidebar. A "you might also like" widget. None of these carry meaningful weight for topical authority because they are boilerplate, repeated across the site, and discounted accordingly.

I made this mistake on an early build of this site. The cluster hub was in the main nav under "Writing > Programmatic SEO". It looked great in the UI. It was worth nothing to the cluster. The version I run now has the hub linked from the cluster topic page, the spokes, and the breadcrumbs. Same UX result, much stronger signal.

Ultra-wide distant view of an ice cave from far back, the entrance reading as a small bright spot in a vast cold field.
// the entrance from afar · one bright point in cold field

Common mistakes

Five patterns I have either made myself or watched a client team make.

Linking every spoke to every other spoke. The instinct is "more links = more signal". The reality is the opposite. A complete graph (every node linked to every other node) reads as link-farm shape and gets discounted. The 3-5 lateral siblings rule is generous, not restrictive.

Putting the hub in the global nav and calling it interlinked. The hub belongs in the body of spoke articles, the cluster topic page, and breadcrumbs. The global nav is boilerplate and weights near zero.

Using the same anchor phrase from 40 spokes pointing at the hub. Anchor diversity matters. Track the anchors claimed in a registry. Aim for 0.85+ unique phrases per target.

Letting laterals drift across clusters. A spoke in one cluster links laterally to spokes in three other clusters because "the topics touch". The cluster's topical concentration drops, the signal weakens, the rankings stall. Cross-cluster links go through hubs only.

No registry, no audit, no idea which anchor was used where. This is the silent killer. The cluster looks fine in the file system. The actual link graph is sloppy because nobody is keeping track. A 50-line audit script that walks the MDX, counts links, and dumps a CSV catches almost every topology bug in 30 seconds. Write the audit before you ship the cluster, not after.

What to try next

Three things, in order.

The first is to write a small audit script. Walk the MDX files in the cluster. For each file, count outbound links, classify each link as hub-pointing, lateral-in-cluster, lateral-cross-cluster, or external. Output a CSV with one row per spoke and columns for each count. Flag any spoke with fewer than 3 lateral siblings, or any spoke with cross-cluster lateral links, or any spoke missing a hub link. The script is 50 lines of Node or Python. The first run will surface 5-15 bugs in a typical cluster.

The cluster looks fine in the file system. The actual link graph is sloppy because nobody is keeping track.

The second is to run an anchor-diversity check. For each target slug (especially the hub), count unique anchor phrases used to point at it across the cluster. Compute the diversity ratio (unique phrases / total inbound links). Below 0.85 is a flag. The fix is to rewrite the colliding anchors with different surface text that still describes what the reader will find at the destination.

The third is to expand the cluster. Once the topology is clean and the audit comes back green, you can grow the cluster from 12 spokes to 18, then 18 to 25. Depth before breadth, as I argued in the cluster architecture pattern library. The topology is what makes the additional spokes pay off; without it, more spokes means more sloppy graph.

The audit script lives in the same repo as the content. The registry it reads is the same one the writers update. The audit runs in CI on every content PR. If the topology breaks, the build fails. That is the level of discipline a 200-article content program needs to keep ranking signal coherent. It is the discipline I leaned on hardest while building a 640-article content engine for a pre-launch legaltech startup. Anything less and the graph degrades quietly while you ship more articles wondering why traffic plateaued.

I cover the broader picture in the programmatic SEO pillar guide for DTC, and the velocity side of the equation in shipping content at agent-orchestrated cadence. If you want a cluster topology audit on an existing site (link counts, anchor diversity, cross-cluster leakage, hub placement) the DTC stack audit covers it as one of its modules. The full product ladder lives at /products.

For grounding-in-experience on the writer-agent side that fed this topology, see AI-assisted content with real grounding.

Does the hub still need a link from every spoke if the spokes are crawled via the cluster topic page?

Yes. The cluster topic page link is one signal. The body links from every spoke pointing back at the hub are a different signal, weighted higher because they are in-body and from thematically-related pages. Both should exist. The topic-page link does not replace the spoke-body links.

What if my cluster has 50 spokes? Do I still link each to only 3-5 laterals?

The lateral count grows slowly with cluster size. A 50-spoke cluster might have spokes linking to 5-7 laterals each, but the rule "each spoke does not link to more than a small subset of siblings" still holds. The point is to avoid the complete-graph shape. 50 spokes each linking to all 49 others is 2,450 internal links and reads as link-farm. 50 spokes each linking to 5-7 laterals is 250-350 internal links and reads as a real cluster.

Can I add 'related posts' widgets at the bottom of each spoke for the lateral links?

You can, but the widget links count less than body-prose links because they look templated. The strongest version is the body-prose link inside a sentence that would still make sense if the link were removed. The widget is fine as a UX feature; do not rely on it for the topology.

How do I handle a cluster that is missing a hub article?

Write the hub before you write any more spokes. A cluster without a hub is a pile of related posts; it cannot accumulate authority into a single ranking head term because there is no head-term page to rank. The hub is the single most important article in any cluster and the one that should ship first.

Is this topology different for a brand-new site versus an established one?

The topology itself is the same. The order of operations differs. On a new site, ship the hub plus 8-12 spokes with the topology in place from day one. On an established site with existing posts, audit the existing graph, classify what you have, and rewrite the link patterns in batches. Avoid mass rewrites that change every internal link at once; Google reads sudden link-graph changes as a signal too, and you want that signal to be incremental and positive.

Sources and specifics

  • The cluster I am running on this site has roughly 14 clusters and 200+ MDX articles, all live in one repo with a sha256-stamped registry that records anchors claimed.
  • Spokes link to 3-5 lateral siblings, every spoke links back to the hub, hubs do not appear in site-wide nav. Hub-out fan-out is the full spoke list.
  • The pgvector interlink engine on the case-study client kept anchor diversity above a 0.85 uniqueness ratio across 40+ pages by surfacing top-K nearest siblings per spoke and checking the anchorsClaimed map before suggesting a phrase.
  • Site-wide-nav linking dilutes the topical signal because every page sees every link, which carries near-zero relevance weight. Body-prose links from in-cluster pages carry the topical authority signal that ranks the cluster.
  • The registry pattern uses a JSON file with a posts array and an anchorsClaimed map, updated by writers via optimistic sha256 retry so concurrent processes do not collide.

// related

Let us talk

If something in here connected, feel free to reach out. No pitch deck, no intake form. Just a direct conversation.

>Get in touch

Tell me what you’re trying to ship.

Send a quick message and I read it within a day, or talk to AI Michael first if you want to feel out your project before you write to me.

By sending this, you agree to the Terms and acknowledge the Privacy Policy.