calendar Last updated: 18 September 2026
How I Catch Keyword Cannibalization with Search Console and Claude
Data integration

How I Catch Keyword Cannibalization with Search Console and Claude

Try It Free

Connect your data in 1 min. Free forever plan

Got insights from this post? Give it a boost by sharing with others!

Keyword cannibalization, or content cannibalization, is two of our own pages ranking for the same queries and splitting the impressions between them. I find it in Search Console by pulling query and page together, then measuring, for each page in a pair, what share of its own impressions comes from the queries it shares with the other page. That percentage and the position gap on those shared queries decide whether one page gets redirected into the other. Search Console calculates neither, so this is a check I run on the data itself, and these days a question I ask Claude.

Search Console, GA4 and your CMS (WordPress here, since that’s what we run) are three separate places to check, with three logins, three exports and three URL formats that do not match by default. Joined into one table on the same URL key, they become one dataset you can query, and both checks in this post run on that table.

That table makes two things visible that the separate reports do not: keyword cannibalization, and content updates whose results get judged before Google has recrawled the page.

Both show up on any site where more than one person has edited content over time, as strategy shifts and different people make calls without a shared view of what is already live.

I check for both with the cannibalization module in an internal dashboard built around a process I ran by hand for years before it existed: pulling Search Console, GA4, and WordPress data separately and merging it myself in spreadsheets. The dashboard also covers editorial priorities, opportunity scoring and page-level performance. This post is about the two checks above. Making a call between two competing pages takes three sources, each doing a different job:

  • Search Console shows which one Google already prefers, and when it last crawled either.
  • WordPress shows when each was last edited, so you know whether a before/after read is even trustworthy yet.
  • GA4 shows the engagement rate for each, which is how I decide whether the page I’m keeping needs anything from the one I’m redirecting.

How I find keyword cannibalization in Search Console

The pull is query and page together, with impressions and average position for each row, over the last 30 days. Non-branded queries only, and each query needs at least 30 impressions in that window, so a handful of stray impressions doesn’t create a pair.

For every query where two of our pages both show, I work out two numbers per page: the share of its own impressions that comes from the queries it shares with the other page, and its average position on those shared queries only. A page drawing 80% or more of its impressions from queries the other page outranks it on is a merge and redirect candidate. An 80% concentration over 3 shared queries is the same signal as 80% over 30.

Search Console’s Performance report shows one page’s queries at a time and exports 1,000 rows. It has no view that puts two pages next to each other and it doesn’t calculate the share, which is why I ran this in a spreadsheet for years after exporting, and why the cannibalization module in the dashboard exists.

The pair I found

The two pages share eight queries. Page A draws 38% of its own impressions from that shared set, and Page B draws 100%.

The URLs and queries are relabeled. The pages and numbers are real ones from our own site.

  • 38.0% of Page A’s impressions come from these 8 queries
  • 100.0% of Page B’s impressions come from these 8 queries
Query Page A impr. Page A pos. Page B impr. Page B pos.
Query 1 668 3.0 44 3.0
Query 2 26 26.0 46 6.2
Query 3 69 7.9 1 13.0
Query 4 35 6.7 33 9.6
Query 5 17 8.0 2 9.5
Query 6 11 7.2 7 10.7
Query 7 8 9.0 1 7.0
Query 8 4 77.8 3 88.3

Keep Page A. It averages position 4.8 on the shared queries versus 8.1 for Page B, Google already prefers it. Page B should be merged into Page A and redirected, it draws no impressions from outside this overlap.

Unique to Page A: 1,367 impressions outside the shared set. Unique to Page B: none of significant volume.

Page B has no traffic outside the shared queries, and Page A outranks it on every one of them. That’s not visible from either page’s Search Console numbers alone, only when you check what percentage of each page’s traffic comes from the shared set, a percentage Search Console doesn’t calculate for you.

Contrast this with a pair where the overlap is real but partial, say 40% for one page and 20% for the other. Redirecting there is riskier: both pages draw meaningful traffic the other doesn’t touch, so consolidating would throw away real, unique impressions. The shared queries can look the same in both cases, and the percentage is what tells them apart.

Before I redirect anything, I check GA4

Search Console only measures visibility, not what happens after the click. If the losing page has better engagement metrics, I update the winner’s format to match it before redirecting.

So before I acted on the recommendation above, I pulled GA4 engagement data for both pages over the same window:

Metric (last 3 months) Page A Page B
Sessions 53 10
Engagement rate 47.2% 50.0%
Avg. engagement time 31s 22s

Nothing here changes how Page A ends up looking. Page B’s engagement rate edges out Page A’s by under 3 points, but that’s on a sample of 10 sessions, too small to treat as a real difference. Its average engagement time is shorter. If Page B had real volume behind that engagement rate, or if its engagement time were ahead too, that’s the pattern that would send me back into Page A’s content to borrow whatever Page B was doing right, before touching the redirect. Here, there’s nothing worth carrying over.

That is the usual outcome. Most of the time GA4 turns up nothing worth changing about the page I’m keeping. I run the check every time anyway, because when it does turn something up, I want to update that page’s format before the redirect goes in, while the losing page is still live to compare against.

Why I don’t trust a before/after check without a crawl date

The usual way to measure a content update is to change the page, note the date, come back in a couple of weeks and compare Search Console numbers before and after. It reaches the wrong conclusion whenever Google has not recrawled the page in between.

Search Console’s Performance data doesn’t record when Google recrawled a page, only when clicks and impressions were logged. You can get a page’s last crawl date from the URL Inspection tool in the GSC UI, but only one URL at a time, and there’s no way to export it, you’d have to check and note down each URL by hand. Confirming it at any scale means the URL Inspection API instead.

So before trusting a before/after comparison, I check whether Google has recrawled the page since I edited it. If not, I stop. The dashboard also flags this automatically: any edit inside the last 14 days is too fresh to read, on top of Search Console’s 2-3 day reporting delay and GA4 dropping the current day as partial.

New content needs the same check, in reverse. The data point is when the new page’s URL first shows impressions in Search Console, not the publish date. Zero impressions for the first couple of weeks may just mean it’s not indexed yet, not that it’s underperforming.

What I check, every time

On every page pair, whether or not anything looks off:

  • Any pair where one page draws 80%+ of its own impressions from queries the other page already outranks it on gets flagged for a merge or redirect decision.
  • Position gap gets checked on the shared queries specifically, not each page’s overall average position, which is diluted by every unrelated query it also ranks for.
  • Before acting on that flag, I pull GA4 engagement rate and average engagement time for both pages. If the “losing” page is ahead on both, with real session volume behind it, I update the winner’s format to match it before redirecting.
  • Pairs with meaningful traffic unique to both pages get a closer look instead of a redirect. I check whether the overlapping queries matter to each page on its own terms, and how much of each page’s unique impressions they bring in, before deciding whether the two need differentiating or can stay as they are.

How I ask for it instead of exporting it

Once this is one connected dataset, I ask directly instead of exporting three files and comparing them in a spreadsheet. The first prompt is the keyword cannibalization check itself, the same calculation described above, run on connected data:

Which of our page pairs have one page drawing 80%+ of its own impressions from non-branded queries it shares with another page, each query with a minimum of 30 impressions over the last 30 days? Doesn't matter if that's over 3 shared queries or 30.
Pull GA4 engagement rate, average engagement time, and sessions for [url] and [url]. Flag it if either is ahead on both engagement metrics.
Has Google recrawled [url] since I last edited it? If not, don't compare before/after numbers yet, tell me when it's safe to check.
Give me our top 10 cannibalized page pairs, ranked by overlap percentage. For each, show how much traffic each page gets, last crawl date, publish date, and engagement metrics for both.

These are ordinary questions once the sources are connected. Before that, three logins and three URL formats had to be reconciled before the analysis could start.

🚀 See what your own Search Console, GA4, and WordPress data looks like connected in one place. Free forever plan, no credit card. Try Windsor.ai.

What I’m doing about this pair

Before redirecting, I check whether Page B has any content Page A doesn’t, something worth merging in rather than losing. Here it doesn’t: everything Page B ranks for, Page A already ranks for too, and outranks it on average. Page A keeps 1,367 impressions from outside the overlap. Page B’s contribution outside the overlap rounds to nothing, nothing meaningful to lose by redirecting it in.

Conclusion

Keyword cannibalization and measuring an update too early are both common, and both stay hidden unless Search Console, GA4 and WordPress are read together. The three connectors this runs on:

I’ve built this kind of dashboard at previous jobs, more than once, and each time step one was authenticating every source myself, which takes a few minutes per connector and does not always go smoothly. Through Windsor’s connectors I can also share the dashboard, or a Claude skill built on it, with a teammate without handing over an API key, and with anyone who already has the same connectors set up on their side.

The tools behind this

I pull this from our own Google Search Console, Google Analytics 4, and WordPress connectors. If you also want this queryable from Claude, here’s the Windsor MCP setup guide.

FAQs

What is keyword cannibalization?

Two or more of your own pages ranking for the same queries and splitting the impressions between them, so neither performs as well as one consolidated page would. The number to look at is the share of a page’s own impressions that comes from queries another page already outranks it on. A page at 80% or more is a merge and redirect candidate, whether that concentration sits over 3 shared queries or 30.

Tired of juggling fragmented data? Get started with Windsor.ai today to create a single source of truth

Let us help you automate data integration and AI-driven insights, so you can focus on what matters, growth strategy.
g logo
fb logo
big query data
youtube logo
power logo
looker logo