Say you run a small blog about home espresso and you open Google Search Console. The Queries tab says “how to descale an espresso machine” earned 3,100 impressions in 90 days at an average position of 12.9. One query, one number, page two. Nothing looks wrong.
Filter the report to that query and switch to the Pages tab and it looks different. Two of your URLs are earning those impressions.
/blog/descale-espresso-machine/ 1,700 impr pos 11.8 38 clicks
/blog/espresso-machine-cleaning-guide/ 1,400 impr pos 14.2 23 clicks
That is keyword cannibalization, two of your own pages competing for one search. Google shows one, then the other, and neither collects the clicks, links and history that would push a single page onto page one. The Queries tab could not show you this, and a Claude tool that ranks for this search finds it, out of the box, by reading your titles rather than your rankings. This guide is the workflow we use with the tool we build, ContextBolt SEO, which reads your Search Console and the live results page from inside Claude. Every step names what it costs.
- Cannibalization is a Search Console fact, not a content-audit guess. Two URLs each earning a real share of one query’s impressions is the test. Similar titles are not.
- The Queries tab hides it by design. Two of your results for one query count as one impression at the higher position. You have to filter to the query and break the data down by page.
- Claude cannot see your Search Console or the live results on its own. Connect both through MCP and it becomes the analyst. ContextBolt SEO is a full SEO toolkit that runs inside the agent, reads your connected Search Console for free, and pulls the live top ten for one credit.
- Six steps. Top queries, break down by page, check whether Google keeps switching, read the live SERP, pick the winner and the fix, verify it landed.
- A full pass costs under ten credits. The Search Console calls are free, and the 7-day free trial includes 100 credits.
What keyword cannibalization is, and what it is not
Search Engine Land’s cannibalization guide defines it as two or more pages from one domain targeting the same keywords and the same intent, and it adds a line most people skip. Having more than one page rank is not always a problem. It becomes one when the pages fail to serve distinct needs.
That line matters, because the word gets used for three different situations and only one of them needs fixing.
Two pages both on page one: Your guide sits at 3 and your comparison sits at 7 for the same broad term. That is two results where a rival gets one. Leave it alone.
A hub under its own posts: Your /espresso/ category page shows up at 30 for a query that one of its posts holds at 6. That is normal. The hub is not competing, it is being crawled.
Two pages splitting the demand, both off page one: The descaling example above. Google alternates, the impressions divide, the clicks divide, and the links people give to “your descaling guide” land on whichever URL they happened to find. This is the case this post is about, and it is far more common than the other two on any site that has been publishing for more than a year, because the writer in 2025 did not remember the post from 2023.
The tell is not that two pages exist. It is that the demand is split and neither page is winning.
Why the Queries tab cannot show you this
Google documents this in the Performance report help page. Data grouped by query is aggregated by property. If two results from your site appear for one query, they count as a single impression, and Google’s definition of position says the value shown is the topmost position a link to your property occupied. Data grouped by page is aggregated by page.
Read that again with the descaling example in mind. The Queries tab said 3,100 impressions at 12.9. That row is both pages averaged together, because on each search Google showed one of them, and on any search where it showed both, the row counted once at the higher position. The 1,400 impressions the second page earned are folded in. From the query side, the second page does not exist.
So the check has to be done from the page side, one query at a time. Filter to a query, switch the dimension to page, and see how many of your URLs come back. On a site with 200 posts and 100 queries that matter, that is 100 filtered reports, which is why almost nobody does it by hand and why the checkers that exist take a shortcut.
The shortcut is reading your content instead of your rankings. A Claude Code cannibalization detector that ranks for this query extracts keywords from each post’s title, H1, meta description and H2 headings, then scores text similarity to find posts that would compete. That is a useful audit of your titles. Out of the box it is not a cannibalization check, because without its optional paid SERP key it cannot tell you whether Google is actually splitting a query between two pages, and it will flag two posts with similar headings that Google ranks for entirely different searches. Cannibalization is something Google does with your pages. The place it is recorded, for free, is your Search Console, and that is where the check has to start.
Why Claude cannot do it alone
Ask Claude “which of my pages are cannibalizing each other” with nothing connected and it will read your sitemap or your titles and guess. The guess will sound right. It has no ranking data, no Search Console access and no idea what Google showed for any query last week.
The fix is MCP, the open standard Anthropic introduced in late 2024 for connecting an agent to live data. Connect Claude to your Search Console and to a live SERP source and it stops guessing. It calls a tool, reads the real per-page rows, and does the part it is good at, which is running the same filtered report 100 times, noticing the pattern, and arguing about which page should win.
That split holds for the rest of the guide. The tools fetch. Claude compares and decides. The content gap analysis guide uses the same per-page Search Console call to ask a different question, whether any page of yours earns impressions for a topic at all. This post asks the opposite one, whether too many do.
Step 1: pull the queries worth checking
Start with demand. In ContextBolt SEO the tool is search_console_performance, which reads your connected property broken down by query, page, country, device or date. It costs no credits. Ask for 90 days, because a split that shows over 28 days may just be one week of Google testing, and ask for the maximum 100 rows.
Copy this prompt
From my Search Console, pull my top 100 queries by impressions over
the last 90 days. Keep the full table in the conversation.
Drop any query under 50 impressions. Drop my brand name and anything
containing it. The rest is the candidate list for a cannibalization check.
The two drops matter. A query with 30 impressions in three months cannot tell you anything about which page Google prefers, and your brand name will show every page on your site, which is not cannibalization, it is navigation. What is left is usually 40 to 80 queries on a mid-sized site.
Step 2: break each query down by page
This is the step that finds it. For each candidate, run the same tool with the dimension switched to page and a query filter applied. The filter is a “contains” match, so “descale espresso machine” also catches “how to descale espresso machine” and “descale espresso machine vinegar”, which is what you want, because those phrasings are the same page.
Copy this prompt
For each query on the candidate list, pull my Search Console data
over 90 days broken down by PAGE, filtered to queries containing that
query. Show every URL with impressions, clicks and average position.
Flag a query as SPLIT when two or more of my URLs each hold at least
15% of its impressions. Skip queries where one URL holds 85% or more.
Show me the SPLIT list as a table: query, each URL, its share of
impressions, its position.
The 15% line is ours, not an industry standard. Below it, the second URL is usually a hub page or a post that mentions the term in passing, and Google is not confused about which page is which. At 15% or above, both pages are being shown often enough that the demand is genuinely divided. Move it to 20% on a site with a lot of category pages and to 10% on a site with a few hundred posts and no hubs.
What comes back for the espresso site looks like this.
| Query | URL | Share of impressions | Avg position |
|---|---|---|---|
| descale espresso machine | /blog/descale-espresso-machine/ | 55% | 11.8 |
| /blog/espresso-machine-cleaning-guide/ | 45% | 14.2 | |
| espresso grind size | /blog/espresso-grind-size/ | 71% | 8.4 |
| /blog/dialing-in-espresso/ | 29% | 19.6 | |
| best budget espresso machine | /best-espresso-machines/ | 52% | 22.1 |
| /blog/best-espresso-machine-under-300/ | 48% | 24.7 |
Three splits out of 60 candidates, which is about the rate to expect. Notice that the three are not the same problem. The first is two posts on one job. The second is a post that owns the query and a second post that touches it. The third is a roundup and a price-bracket post that Google cannot tell apart. Steps 3 and 4 tell them apart.
Step 3: is Google switching, or has it already decided?
Two URLs sharing a query over 90 days can mean two different things. Either Google shows both on most days, or it showed one URL for six weeks and then swapped to the other and stayed there. The first is a live split. The second is Google having already picked a winner, and the “loser” is history.
The daily series settles it. Run the same tool with the dimension set to date, filtered to the query and to one URL, then again for the other URL.
Copy this prompt
For each SPLIT query, pull my Search Console impressions by DATE over
90 days, filtered to that query and to the first URL. Then the same
for the second URL. Compare the two series week by week.
Tag the query FLIPPING if the leading URL changes from week to week,
DECIDED if one URL has led every week for the last four,
and name which URL is leading now.
A flipping query is the one that costs you. Google has two candidates it rates about the same and it is testing them, so each page earns half the history and neither gets the momentum. A decided query is cheaper to fix, because Google has done the choosing and your job is to confirm it and stop the other page arguing.
For the espresso site, “descale espresso machine” comes back flipping, with the two posts trading the lead five times in 13 weeks. “Espresso grind size” comes back decided, with the dedicated post leading every week and the dialing-in post drifting on the edge. The budget query comes back flipping, and it is the one where the wrong page might be winning, which is what the next step is for.
Step 4: read the live results page
Search Console tells you what Google did over 90 days. It does not tell you what Google is doing today, or what kind of page it is ranking around yours. For that you read the live page.
serp_overview returns the top organic results for a keyword, with position, domain, title and URL. One credit per query, so run it only on the flipped and decided queries from Step 3, not on all 60 candidates. On a typical pass that is five to ten credits. The full method for reading a results page is in SERP analysis with Claude; here you want two things from it.
Copy this prompt
For each SPLIT query, show me the live top 10.
Tell me which of my URLs appears, at what position, and whether both do.
Then describe the other nine results in one line each: guide, roundup,
product page, forum, video. Tell me whether the page of mine that
Google is showing today matches the shape of the pages around it.
The second half of that prompt is the part people skip. On “best budget espresso machine” the espresso site’s live result is the roundup, at 21, on a page where eight of the other nine results are also roundups with prices in the title. The under-$300 post is the page that matches the query’s shape, and Google is showing the other one. That is the case where the URL Google currently prefers is not the URL that should win, and it changes the fix.
Step 5: pick the winner and the fix
Now the decision, and here is the opinion this post is built on. Keep the page Google already prefers unless Step 4 showed it is clearly the wrong shape. People fix cannibalization by keeping the page they like, the newer one, the one with the better writing, and redirecting the one Google was ranking. That throws away the history of the page that was winning. Google’s preference is data. Your preference is taste.
Three fixes, in order of how often they are right.
Consolidate: The two pages answer the same question. Merge the useful parts of the loser into the winner and redirect the loser’s URL to it permanently. Google’s page on consolidating duplicate URLs calls a redirect a strong signal that its target should become the canonical, and it explains why consolidating is worth doing at all. It lets Google combine the signals it holds for each URL, links included, into one preferred URL. A redirect also moves the reader, which a canonical tag does not. This is the fix for the descaling pair.
Re-key the loser: The two pages answer different questions and Google is confused because they use the same words. Retitle the loser around the question it actually answers, cut the section that overlaps, and link it to the winner with an anchor that says what each page is for. “Dialing in espresso” is a real topic that is not “grind size”, so it gets a title about dialing in, loses its 400-word grind-size digression in favor of one link, and the split closes without deleting anything.
Set a canonical: Only when the two pages are near duplicates you have to keep serving, such as a print version or a filtered variant. A canonical is a hint. Google can and does pick a different canonical than the one you set, and the Page Indexing report has a status for exactly that, Duplicate, Google chose different canonical than user. If you have a real choice between a canonical and a redirect on two blog posts, the redirect wins.
One fix that is not a fix: Deleting the loser without a redirect. The page had links and history, and a 404 hands both to nobody. The duplicate without user-selected canonical status is what you see when two pages compete and you have told Google nothing about which one you meant. Tell it.
| What Steps 3 and 4 showed | Fix | Espresso example |
|---|---|---|
| Flipping, both pages answer the same question | Consolidate into the URL Google prefers, redirect the other | Two descaling posts become one |
| Decided, pages answer different questions | Re-key the loser, cut the overlap, link across | Dialing-in post stops covering grind size |
| Flipping, the preferred page is the wrong shape | Re-key the preferred page away from the query, cut its overlapping section, link it to the page that matches the SERP | Roundup drops its budget section and links to the under-$300 post |
| Near duplicates you must keep serving | Canonical on the variant | Print or filtered versions only |
The third row deserves a word, because it is the uncomfortable one. Taking a query away from the page Google currently ranks feels backwards. It is the right call when that page is the wrong shape for the query and is unlikely to climb from 21, and the shape test in Step 4 is what earns you the right to make it. It is not a redirect, because the roundup still holds every other query it ranks for, and a redirect would hand those to nobody. Cut the section, add the link, and let Google re-sort the two. Without the shape test, keep the winner.
Copy this prompt
For each SPLIT query, using the FLIPPING or DECIDED tag and what the
live top 10 showed, recommend one fix: CONSOLIDATE (name the URL to
keep and the one to redirect), RE-KEY (name the URL to retitle and
the question it should own), or CANONICAL. Give one sentence of
reasoning per query. Default to keeping the URL Google is showing
today unless it does not match the shape of the other results.
Step 6: verify the fix landed
A redirect that is not crawled has not happened yet. After the change, check the losing URL with inspect_url, which reads its index status, coverage state, last crawl date and the canonical Google has chosen from your Search Console, at no credit cost. On a redirected URL you want to see the redirect picked up. On a canonical you want Google’s chosen canonical to match yours.
Then wait. Search Console data lags two to three days, and the losing URL has to be recrawled before anything consolidates, so re-run the Step 2 breakdown on the fixed queries after four to six weeks.
Copy this prompt
Inspect these URLs I redirected last month and tell me whether Google
has picked up the redirect and what canonical it now reports.
Then re-run the per-page breakdown for their queries over the last
28 days and compare it to the 90-day split we found: is each query now
landing on one URL, and has its average position tightened?
What success looks like on the descaling query is one URL carrying close to 100% of the impressions at a position better than either page held alone. A query that consolidates onto one URL and settles between position 5 and 20 is now a candidate for the striking distance check, which is the next job. If the impressions consolidated and the position did not move, the pages were splitting the demand but the ceiling was authority, and that is a different job, backlink research with Claude.
The whole thing as one prompt
Once you have walked it by hand, the six steps collapse into one instruction. This is the version worth saving and running each quarter.
Copy this prompt
Run a keyword cannibalization check on my site from Search Console.
1. Pull my top 100 queries by impressions over 90 days. Drop queries
under 50 impressions and anything containing my brand name.
2. For each remaining query, break the data down by page. Flag SPLIT
where two or more of my URLs each hold at least 15% of impressions.
3. For each SPLIT query, pull impressions by date for each URL and tag
it FLIPPING or DECIDED. Name the URL leading now.
4. Show the live top 10 for each SPLIT query. Say which of my URLs
appears and whether it matches the shape of the pages around it.
5. Recommend CONSOLIDATE, RE-KEY or CANONICAL per query with the URL
to keep. Default to the URL Google shows today unless it is the
wrong shape.
Tell me the credits this will cost before you start. Only the live
SERP step costs credits.
The last two lines are a habit worth keeping. The agent quotes the cost, you say go, and the Search Console half of the job stays free however many queries it checks.
What it costs, in credits
Every tool above is a ContextBolt SEO tool with a fixed price, so the bill adds up before you start. The example is a pass that finds eight split queries.
| Step | Tool | Calls | Credits |
|---|---|---|---|
| Top queries | search_console_performance | 1 | 0 |
| Break down by page | search_console_performance | One per candidate query, about 60 | 0 |
| Daily series | search_console_performance | Two per split query, 16 | 0 |
| Live top 10 | serp_overview | One per split query, 8 | 8 |
| Verify | inspect_url | One per redirected URL | 0 |
| Total | 8 |
Eight credits out of 1,000 a month on the $35 plan, and the 7-day free trial comes with 100, so the first check and the next eleven are covered before any money moves. The reason it is that cheap is structural. Cannibalization lives in your own Search Console data, which is yours and costs nothing to read, and the paid step is a handful of live SERP reads on the queries that turned out to matter. A tool that finds cannibalization by pulling a SERP for every keyword you rank for is spending a credit per row to learn what your Search Console would have told it for free.
Running it with ContextBolt SEO
ContextBolt SEO is a hosted SEO MCP server. Start a 7-day free trial, paste one URL into Claude, Cursor, Codex or ChatGPT, connect your Google Search Console property once, and ask in plain language. Nothing to install, no data vendor account to fund. The Search Console and URL inspection tools above are the free half of the toolkit, sitting alongside keyword research, difficulty, live SERPs, site audits, backlinks and AI visibility checks. You do not pick a tool, you ask. The setup for the Search Console side is in connecting Search Console to an AI agent.
Every lookup saves automatically to your SEO Board, a live dashboard where the SERP reads from this check sit with the date they were pulled, so the “verify” step next month starts from what you found rather than a fresh conversation. The split list itself is the conversation’s output, so paste it into wherever you track site work. A cannibalization check is a snapshot, and the habit that pays is running the one-prompt version every quarter, the way the SEO automation guide schedules it.
On the numbers, the honest framing is the one we hold everywhere. Your Search Console rows are Google’s own data about your site and they are exact. The live SERP is what Google returned at the moment of the call and can differ by location and device. Neither is an estimate, which is part of why this particular job suits an agent so well. The judgment call is which page should win, and that is what you are reading the data for.
Where the check stops
Three limits, stated plainly.
A split is not automatically a problem. Two pages on page one for one query is a good outcome. Steps 3 and 4 exist to separate a genuine split from Google giving you two slots, and a check that skips them will have you merging pages that were both winning.
The “contains” filter is generous. Filtering to queries containing “espresso machine” will also pull “espresso machine repair” onto the page breakdown, and a repair post earning impressions there is not cannibalizing your buying guide. Read the query list Claude actually matched before you act on a share figure, and tighten the filter string when a broad term comes back noisy.
Never automate the fix. A consolidation is a permanent redirect and a merged page, and getting the direction wrong costs you the ranking of both. The check can and should run on a schedule. The redirect is a decision a person makes after reading the live page, which is why Step 4 is in this guide at all.
The list you are left with is short, usually three to ten queries, each with the two URLs, the share each holds, which one Google is showing today, and a recommended fix with a reason. That is an afternoon’s work laid out from one conversation, and it will recover rankings you already earned and then split in half. ContextBolt SEO starts with a 7-day free trial, so the first check costs nothing.