Free SEO tool. Search Console data
Keyword Cannibalization Checker: Free, Runs in Your Browser
Paste Search Console rows that carry both the query and the page. The checker groups them by query, finds where two or more of your URLs split the impressions, and suggests which splits to merge, which to separate and which to leave alone.
Privacy: nothing you paste or upload leaves your device. The file is read and processed by JavaScript in this browser tab. Nothing is sent to a server or saved.
Most cannibalization checks stall at the data step. Search Console’s Performance export puts queries and pages in separate tabs, so you can see that a query had impressions and that a page had impressions, but not which page earned them for which query. This checker needs the joined version, and the three ways to get it are in the how-to under the tool. Once you’ve got your list of flags, the keyword cannibalization guide covers how to fix each one.
1. Your Search Console rows
2. Settings
Queries with fewer impressions in total are skipped as noise.
A query is flagged when 2 or more pages each hold at least this share of its impressions.
Any query containing one of these is left out.
Flagged queries
Swipe the table sideways to see each page and the reason.
Page pairs that collide
A split isn’t always a problem: sitelinks, two listings in the top 3 and queries with two real intents all show more than one of your URLs. When a flag is real, the diagnose and fix guide walks through picking the winning page, the 301 and the internal links.
Quick answer
This keyword cannibalization checker reads Search Console rows that include both the query and the landing page, then flags every query where two or more of your URLs each take a real share of the impressions (10% by default). Each flag gets a suggested action (merge, differentiate intent or ignore) with the reason in plain English, plus a view of which page pairs collide most. It’s for SEOs, content leads and site owners who want a site-wide check without connecting an account or paying for a crawler.
How to Use the Keyword Cannibalization Checker
Six steps. Only the first one is fiddly, because the data you need isn’t in the standard export.
Get query and page rows in one table
Search Console’s own export gives you one table per dimension, and it stops at 1,000 rows. You need a table where every row is one query on one page. Use a Looker Studio table, the Search Analytics for Sheets add-on or the Search Console API, all three explained below.
Paste the rows or upload the CSV
Paste into the box or pick the file. Columns are matched by header name, so order doesn’t matter. Query or Top queries, Page, Landing Page or URL, Clicks or Url Clicks, Impressions, and Position or Average Position all work. CTR is optional.
Set the thresholds and your brand terms
Start with 10 impressions and 10%. On a big site, raise the minimum to 50 or 100 so you only see queries worth an afternoon. Add your brand names, because two pages showing for your own name is normal and clutters the list.
Run it and read the summary
Click Find cannibalization. The summary says how many queries were checked, how many were skipped and why, and how many were flagged, split into merge, differentiate and ignore.
Check the top flags in Search Console
Sort by impressions at stake and take the top 10. Open each query in the Performance report, switch to the Pages tab and compare two date ranges. If the leading URL swaps between periods, the split is real.
Fix the real ones
Use the page pairs table to find pages that collide on many queries, then apply the fix from the keyword cannibalization guide: merge and 301, retarget one page to its own intent, or leave it.
Three ways to get query and page together
The export button in the Performance report gives you a Queries table, a Pages table and a few others, each grouped by one dimension. Google’s help page also notes that exported data is truncated to 1,000 rows. That’s why a Search Console cannibalization report has to come from somewhere else. Any of these works.
Route 1: a Looker Studio table (free, no code)
- In Looker Studio, click Create, then Data source, and pick the Search Console connector.
- Choose your site. In the Tables panel, choose URL Impression. The Site Impression table has no landing page field, so it won’t work here.
- Leave the search type on Web, click Connect, then Create report.
- Add a table chart. Dimensions: Query and Landing Page. Metrics: Url Clicks, Impressions and Average Position. Set the date range to the last 3 months. (Field names can read slightly differently in your account. The checker accepts the common variants.)
- In view mode, right-click the table, choose Export, and save it as CSV.
Looker Studio may group anonymized queries into one row with a blank query. The checker skips those rows and tells you how many it skipped.
Sources: Google’s Search Console connector docs (Site Impression versus URL Impression, blank query rows) and export data from a chart (CSV, CSV for Excel, or Google Sheets).
Route 2: the Search Analytics for Sheets add-on
- In Google Sheets, go to Extensions, then Add-ons, then Get add-ons, and install Search Analytics for Sheets.
- Open it from the Extensions menu, pick your site and a date range, and set Group By to Query and Page.
- Click Request Data.
- Download the sheet as CSV (File, then Download), or select the cells and paste them straight into the box above. Pasted cells arrive tab separated, and the checker reads that fine.
It’s a third-party add-on. Its free plan allows up to 10,000 rows per request and all grouping options. More on the add-on’s site.
Route 3: the Search Console API
Call searchanalytics.query with dimensions set to query and page. rowLimit goes up to 25,000 per request, and startRow pages through the rest. Write the rows to a CSV with a header like query,page,clicks,impressions,ctr,position and upload it. Google notes the API returns the top rows and doesn’t guarantee all of them, so on a big site you’re looking at the top slice.
Already using the bulk data export to BigQuery? Pull query, url, clicks, impressions and sum_position from the searchdata_url_impression table. The checker spots sum_position and converts it with Google’s formula: sum_position divided by impressions, plus 1.
Sources: searchanalytics.query reference, the performance data limits post (1,000 rows in the interface, 50,000 rows per day per site per search type through the API and Looker Studio) and the bulk export table guide.
How to Read the Results
The summary tells you how many queries were checked, how many were skipped and why, and how many crossed the line. Then come two tables.
The flagged queries table
Impressions at stake is every impression your pages got for that query, added up page by page. Pages are labelled A, B, C in order of impressions, each with its share of impressions, its share of clicks and its average position. Greyed pages showed up, just not enough to count as competing.
Click any column header to sort. Impressions at stake is the default, because a split on a 3,000 impression query matters more than a split on a 40 impression one.
What each suggested action means
Two pages of the same kind split the query and neither dominates. Pick the URL with more links and better conversions, move anything unique into it and 301 the other. Also used when two URLs are the same page under different addresses (a trailing slash, www or a sort parameter), where a canonical tag or redirect is the fix.
One URL looks like an article and the other like a product, category or service page. Usually the article is chasing a buying query. Retarget its title and H1 at the question people actually ask, and link from it to the commercial page. The blog versus money page fix covers this case in detail.
One page holds 75% or more of the impressions, or 90% or more of the clicks once there are at least 10. Or every competing page already averages position 3 or better. The second page is a passenger.
The page type comes from the URL path: /blog/, /guides/ or a dated path reads as an article, and /products/, /collections/, /category/ or /services/ reads as commercial. If your URLs don’t say (lots of WordPress sites put everything at the root), the checker falls back to Merge and says it couldn’t tell. That’s your cue to look at the results page yourself.
The page pairs table
This one turns the flags around. Each row is two of your URLs and how many flagged queries they split. A pair that collides on 1 query is a small problem. A pair that collides on 15 is structural: two pages written for the same topic, so every query in that topic gets split. Fix the pair once and all 15 queries move.
Worked example: the sample data
Click Load sample data. It’s a made-up outdoor shop, Acme Trail, on example.com, exported the Looker Studio way: 34 rows, 17 queries, with acme as the brand term. Two brand queries get excluded. Merino hiking socks has 9 impressions, so it falls under the minimum. The size guide’s #boots jump link folds into the main size guide URL, so that query isn’t flagged. That leaves 11 flagged queries: 6 merge, 3 differentiate, 2 ignore.
The biggest flag is waterproof hiking boots, with 3,220 impressions at stake. The hiking boots collection takes 57% at position 14.2, and a blog post on the best waterproof hiking boots takes 41% at 17.8. Article versus collection, so the checker says differentiate. The post is chasing a buying query, and neither page is on page one.
The pairs table shows the bigger story. The boot care guide and the how to waterproof boots post collide on 3 queries (how to waterproof hiking boots, hiking boot care and how to clean hiking boots), and both sit between positions 8.1 and 19.5. That’s one topic written twice. Merge.
Trekking poles is a different kind of merge: the collection and the same collection with ?sort_by=price-ascending split the query. A canonical tag or a 301 sorts that out, and nobody has to rewrite anything. And two flags say leave it: trail running shoes, where the collection holds 89% of impressions, and hiking backpack 30l, where both pages already average position 3 or better.
When Split Impressions Aren’t Cannibalization
A flag is a question. Plenty of splits are fine, and the checker can’t see the results page.
- Sitelinks and double listings. When Google shows two of your pages for one search, each URL logs its own impression when data is grouped by page (Google explains the counting here). Two of your pages in the top 3, or a result with sitelinks under it, is usually a win.
- Two real intents. A query like hiking boots can mean show me boots or help me choose. If Google keeps your category and your guide on page one together, it may want both.
- Brand searches. Your home page, about page and product pages all showing for your name is normal. That’s what the brand filter is for. If you haven’t got a clean brand list, the branded vs non-branded keyword splitter helps you build one.
- Short tests. Google sometimes tries a second URL for a week or two. One export can’t show that, so compare two date ranges before acting.
When the split is real, the pages chase the same searcher and neither climbs. The keyword cannibalization guide has the decision framework for that, and the Search Console walkthrough shows the manual check, click by click, for confirming a single query. If a merge means retiring dozens of URLs at once, read how to redirect thousands of URLs without losing traffic first.
Limits of This Checker
- It only sees your file. Search Console leaves out anonymized queries (ones searched by too few people), and the 1,000 row interface cap and 50,000 row API cap mean a big site’s export is the top of the data. Long-tail splits can hide below that.
- No time dimension. The clearest sign of cannibalization is the ranking URL flipping between periods. One export is a single snapshot, so run two date ranges and compare, or check the top flags by hand.
- Page type is a guess from the URL. It doesn’t open your pages, read titles or compare content. Two pages with different intents can still get Merge if their URLs look alike.
- Impressions at stake runs high. It adds up page-level rows, and a search that showed two of your pages counts for both. Expect it to be bigger than the same query’s figure in the Queries tab.
- The brand filter is a plain contains match. A brand term of art would also catch smart watch. Use your full brand name, or a few spellings of it.
- Thresholds are judgment calls. 10% and 75% are starting points. Google doesn’t publish a threshold, so move them and watch how the list changes.
For a sweep that also covers rankings Search Console hides, the Ahrefs and Semrush method finds candidates from rank data. Confirm them with your own Search Console numbers before you change anything.
Keyword Cannibalization Checker FAQ
What does a keyword cannibalization checker do?
It looks through your search data for queries where more than one of your pages shows up, then picks out the ones where the split is big enough to matter. This one works from your own Search Console rows, so the numbers are Google’s, not a rank tracker’s estimate.
Is this keyword cannibalization tool free?
Yes. There’s no signup, no Search Console connection and no row cap set by the page. It runs in your browser, so your data never reaches a server.
Why doesn’t the normal Search Console export work?
The Performance report export puts queries and pages in separate tables, so you can’t tell which page earned which query, and it stops at 1,000 rows. A Looker Studio table, the Search Analytics for Sheets add-on or the Search Console API gives you both dimensions in one table.
What share threshold should I use?
Start with the default: 2 or more pages each holding at least 10% of a query’s impressions. On a small site, drop it to 5% to see more. On a big site, raise it to 20% and lift the minimum impressions so only serious splits show.
Does two of my pages showing for one query always mean cannibalization?
No. Sitelinks, two listings in the top 3, brand searches and queries with two genuine intents all show more than one URL and are usually fine. It’s a problem when the pages chase the same searcher and neither one climbs.
Why are the impressions here higher than in my Queries tab?
Search Console counts impressions per URL when data is grouped by page, so if two of your pages appear in the same search, both get one. The Queries tab counts that search once for the whole site. The checker adds up page rows, so its totals can be higher.
How big a file can it handle?
In testing it checked 50,000 rows in under a second in desktop Chrome. Upload a file that size, because pasting 4 MB of text into the box is slow. The Search Console API and Looker Studio stop at 50,000 rows per day per site per search type anyway, so that’s the usual ceiling.
What should I do with the flagged queries?
Check the top 10 by impressions in Search Console across two date ranges. Then apply the fix for each: merge and 301, retarget the weaker page to its own intent, or leave it. The keyword cannibalization guide walks through each move.
Keep going
- Keyword cannibalization: how to find and fix it (the full guide this tool pairs with)
- How to identify keyword cannibalization in Google Search Console
- Finding keyword cannibalization with Ahrefs and Semrush
- Content cannibalization: when your blog outranks the money page
- 7 Search Console reports most marketers never open
Got a long list and no time to sort it?
A flagged list isn’t a fix list yet. An SEO audit turns it into one: which page wins each query, what to merge or redirect, and in what order.
See the SEO audit



