Keep a page that earns clicks, improve one that gets impressions but few clicks, merge or redirect one with weak impressions into a better page, redirect any page that other sites link to, and delete or noindex pages with no clicks, no impressions and no links. Check the exceptions by hand.
Key takeaways
- Three signals cover most decisions: clicks over a long window, impressions, and referring domains.
- Redirect before you delete if anything links to the page. Google documents permanent redirects as a signal that the target should be canonical, so the redirect carries the old page forward.
- 404 and 410 both remove a page. Google documents that it treats a 410 much like a 404, so the choice is not a ranking lever.
- Noindex keeps the page for readers but out of search. It only works if the page stays crawlable; see the robots.txt trap below.
- Pruning is not a proven ranking boost. Google publishes no rule that deleting thin pages raises the rest, so remove pages because they are useless, not for a promised lift.
The three signals
- Clicks over 12 months from the Performance report (use a long window so seasonal pages are not cut).
- Impressions, which tell you whether Google shows the page at all.
- Referring domains from a backlink export. Even a free backlink report is enough for a yes/no.
The decision rules
| Situation | Action | Basis |
|---|---|---|
| 10+ clicks and a healthy click rate | Keep | Practice |
| 10+ clicks, very low click rate | Improve the title and snippet | Practice |
| Few clicks, but another site links to it | Redirect to the closest page, or merge | Documented: permanent redirects signal the target as canonical |
| Few clicks, some impressions, no links | Merge into a stronger page, then redirect | Practice |
| No clicks, no impressions, no links | Delete (404 or 410) or noindex | Documented: 404 and 410 both drop a URL |
The sorting script
Give it the Performance export (Page, Clicks, Impressions) and, optionally, a CSV of
Page, Referring domains. Pages that only appear in the links file are included, so an orphan with
backlinks is not missed:
import csv, sys
# argv: pages.csv (Page, Clicks, Impressions over 12 months) [links.csv (Page, Referring domains)]
num = lambda s: int(str(s).replace(',', '') or 0)
pages = {r['Page']: (num(r['Clicks']), num(r['Impressions'])) for r in csv.DictReader(open(sys.argv[1], encoding='utf-8-sig'))}
links = {}
if len(sys.argv) > 2:
links = {r['Page']: num(r['Referring domains']) for r in csv.DictReader(open(sys.argv[2], encoding='utf-8-sig'))}
for u in links:
pages.setdefault(u, (0, 0))
groups = {'KEEP': [], 'IMPROVE': [], 'REDIRECT or MERGE (has links)': [], 'MERGE (has impressions)': [], 'DELETE or noindex (no clicks, impressions or links)': []}
for u, (clicks, imp) in sorted(pages.items()):
rd = links.get(u, 0)
if clicks >= 10:
g = 'KEEP' if imp and clicks / imp >= .01 else 'IMPROVE'
elif rd >= 1:
g = 'REDIRECT or MERGE (has links)'
elif imp >= 100:
g = 'MERGE (has impressions)'
elif imp == 0:
g = 'DELETE or noindex (no clicks, impressions or links)'
else:
g = 'MERGE (has impressions)'
groups[g].append((u, clicks, imp, rd))
for g, items in groups.items():
print('\n%s: %d' % (g, len(items)))
for u, c, i, rd in items[:8]:
print(' %-34s clicks %-4d impressions %-5d linking domains %d' % (u, c, i, rd))
I tested it on seven pages built to cover each rule once. All seven landed in the intended group, including a page with zero clicks and zero impressions but four linking domains, which went to redirect rather than delete, and a page with 30 clicks out of 9,000 impressions, which went to improve rather than keep.
Exceptions to check by hand
- New pages. Anything younger than a few months has no history, so it will sort into "delete" for the wrong reason.
- Pages that serve other goals: legal, contact, pricing, conversion pages that get no search traffic by design.
- Seasonal pages, which a short window will undercount.
- Pages that are noindexed already, which show no impressions for a reason.
When you noindex, do not also block the URL in robots.txt. A crawler that cannot fetch the page never sees the tag, which is the trap explained in noindex vs robots.txt disallow. If you redirect many URLs at once, test the map with the redirect checker.