Keyword clustering means sorting your keywords into groups that one page can rank for. The most reliable way to do it is to compare Google’s results. If two keywords show many of the same pages in the top 10, Google treats them as one topic, and one page can target both.
This guide covers the idea in plain words, a spreadsheet method you can do by hand, and a short Python script that does it for you.
What keyword clustering is
Keyword clustering is grouping keywords so that each group maps to one page on your site. It stops you from writing three pages that compete for the same search, and from cramming two different searches into one page.
There are two common ways to group keywords:
- By meaning. You, or a tool, group keywords that look or sound alike. Keyword clustering and keyword clustering tool land together.
- By SERP overlap. You fetch the Google results for each keyword and group the ones that share ranking pages. Google decides what belongs together.
Grouping by meaning is fast, but it guesses. Grouping by SERP overlap checks the guess against the results page you want to rank on.
Why SERP overlap beats grouping by meaning
We pulled the US English desktop results for 11 closely related keywords on October 9, 2026, using a SERP API (DataForSEO’s). Then we counted how many top 10 URLs each pair of keywords shared. Of the 55 pairs, only 3 shared any URL at all, and only 1 pair shared 3 or more.
| Keyword pair | Shared top 10 URLs |
|---|---|
| keyword clustering + what is keyword clustering | 4 |
| keyword clustering + keyword grouping | 1 |
| what are sitelinks + how to get sitelinks | 1 |
| keyword clustering + keyword clustering tool | 0 |
| click through rate formula + how to calculate click through rate | 0 |
| click through rate formula + ctr calculator | 0 |
A grouping by meaning would put all of these pairs together. Google did not. The results for keyword clustering tool were mostly lists of tools and tool home pages, while keyword clustering mostly showed guides. The ctr calculator results were calculator pages, and click through rate formula showed explainers from finance and email marketing sites.
So one guide aimed at both keyword clustering and keyword clustering tool would be fighting two different results pages. Those searchers want different things, and the results show it. This is the same reading you do in a SERP analysis, applied to a whole keyword list at once.
How to cluster keywords in a spreadsheet
This works well for up to about 50 keywords.
-
List your keywords in column A, one per row, with the most important (often the highest volume) at the top.
-
Get the top 10 URLs for each keyword. Search in a private window with your target location set, or export them from a rank tracker. Our guide to checking Google rankings shows how to see the page that searchers see. Paste the 10 URLs into columns B to K of the keyword’s row.
-
Count the overlap with the top keyword. In row 3, column L, this formula counts how many of row 3’s URLs also appear in row 2. Copy it down the column.
=SUMPRODUCT((B3:K3<>"")*COUNTIF($B$2:$K$2,B3:K3)) -
Group the matches. Every keyword with a count of 3 or more joins the top keyword’s group.
-
Repeat with the next keyword that is not in a group yet. Point the
$B$2:$K$2part of the formula at its row and count again.
Clean the URLs before you compare them. The same page with and without www, or with a #section on the end, will not match in a sheet. Use find and replace to strip https://, www. and anything after a #.
How to cluster keywords with Python
For bigger lists, a script saves hours. The one below has two parts. The cluster function takes a list of URLs for each keyword, so it works with data from any source. The top_urls helper fills that list from a SERP API, using the documented POST /v1/serp/search request, which returns the page’s results in data.items.
import requests
API_KEY = "live_your_key_here"
def top_urls(keyword, location_code=2840, device="desktop"):
"""Fetch one Google results page and return its top 10 organic URLs."""
r = requests.post(
"https://api.serplify.io/v1/serp/search",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"keyword": keyword,
"location": {"code": location_code},
"language": {"code": "en"},
"device": device,
"depth": 10,
"format": "standard",
},
timeout=60,
)
r.raise_for_status()
body = r.json()
if body["status"] != "ok": # "accepted": the search moved to the task queue
raise RuntimeError(f"{keyword}: not ready, poll {body['data']['status_url']}")
organic = [i for i in body["data"]["items"] if i["type"] == "organic"]
organic.sort(key=lambda i: i["rank_group"])
return [i["url"] for i in organic[:10]]
def clean(url):
"""Make two links to the same page look the same."""
url = url.split("#")[0].rstrip("/")
for prefix in ("https://", "http://", "www."):
url = url.removeprefix(prefix)
return url
def cluster(serps, min_shared=3):
"""Group keywords whose top 10 URLs overlap.
serps maps each keyword to its list of top URLs. Put your most
important keywords first: each group starts from the first unused one.
"""
pages = {kw: {clean(u) for u in urls} for kw, urls in serps.items()}
groups, used = [], set()
for seed in serps:
if seed in used:
continue
group = [seed]
used.add(seed)
for kw in serps:
if kw not in used and len(pages[seed] & pages[kw]) >= min_shared:
group.append(kw)
used.add(kw)
groups.append(group)
return groups
if __name__ == "__main__":
keywords = ["keyword clustering", "keyword clustering tool", "what is keyword clustering", "keyword grouping"]
serps = {kw: top_urls(kw) for kw in keywords}
for group in cluster(serps):
print(group)
It needs Python 3.9 or newer and the requests package. We ran the cluster function on the top 10 URLs we pulled for these four keywords on October 9, 2026. It printed three groups:
['keyword clustering', 'what is keyword clustering']
['keyword clustering tool']
['keyword grouping']
That is one page for the first two keywords, and separate pages (or no page) for the other two.
If your URLs come from somewhere else, such as a rank tracker export or another API, skip top_urls. Build the serps dictionary yourself, with each keyword pointing to its list of URLs, and pass it to cluster.
Compare URLs, not domains
It is tempting to match on domains instead, because more pairs match. Do not do it. In our 11 keyword test, how to calculate click through rate and what are sitelinks shared two domains, adriel.com and quora.com. They shared zero pages. Big sites rank for hundreds of unrelated topics, so a domain match says almost nothing about intent.
How many shared URLs should count as a match?
The min_shared number sets how strict the grouping is. Tools let you choose it too. SE Ranking, for example, lets you set it anywhere from 1 to 9 shared URLs.
- Lower numbers (1 or 2) make bigger groups, with more risk of mixing different intents. At 1, our test merged keyword grouping into the keyword clustering group because of a single shared page.
- Higher numbers (4 and up) make small, tight groups and leave more keywords alone.
We start at 3 and then read the groups by eye. If a group looks wrong, look at the two results pages side by side before you trust the number.
The script above compares each keyword with the group’s first keyword only. SE Ranking calls this soft grouping, and it uses the highest volume keyword as that first keyword. Hard grouping requires every keyword in a group to match every other one. It makes smaller groups, and it catches more mixed intents.
How to turn clusters into pages
- One cluster, one page. The first keyword in the group is the page’s main keyword, so judge keyword difficulty on that keyword’s results. Use the others in headings, in the intro and in the FAQ.
- Groups of one still count. A keyword that matched nothing either needs its own page or does not fit your site.
- Check what you already have. If two of your pages target the same cluster, merge them or make them clearly different. Otherwise they compete with each other.
- Re-run it later. Results change, so a cluster is a snapshot. Check again before a big content plan, and use bulk rank tracking to see which page Google picks for each keyword once you publish.
What SERP clustering costs
You need one results page per keyword. Checking by hand is free but slow. With an API, the cost is the price per results page times the number of keywords.
At Serplify’s price of $0.005 per results page (checked October 2026), 500 keywords cost $2.50 to fetch once. Details are on the SERP API page. Store the URLs you fetch, and you can re-cluster with a different min_shared value without paying again.
Frequently asked questions
What is keyword clustering?
Keyword clustering is sorting a keyword list into groups that one page can rank for. The SERP method puts two keywords in the same group when Google shows many of the same pages for both. Each group then becomes one page on your site.
What is an example of keyword clustering?
On October 9, 2026, the US results for keyword clustering and what is keyword clustering shared 4 of their top 10 pages, so one guide can target both. The results for keyword clustering tool shared none of them and were mostly lists of tools, so that keyword needs a different page.
How many keywords should be in a cluster?
There is no set number. A cluster holds every keyword that shares enough results with the main one. Some clusters have twenty keywords, and many have just one. A group of one is still useful, because it tells you that keyword needs its own page.
Is keyword clustering the same as a topic cluster?
No. Keyword clustering decides which keywords one page should target. A topic cluster is a way to organize many pages, with one main guide that links to related posts and back. You often use keyword clusters to plan the pages inside a topic cluster.
Sources and further reading
- SE Ranking: Keyword clustering, grouping accuracy and soft vs hard grouping seranking.com
- Serplify docs: SERP API response format docs.serplify.io
- Serplify docs: Live search request docs.serplify.io