SEO Measurement: 5 Metrics, Read Off My Own GSC Data
My site earned 22 clicks from 4,553 impressions in 85 days. Here are the five Search Console readings that explain why, and the Python that pulls them out of a CSV export.
Table of contents
SEO measurement means five readings, not a dashboard. Clicks per query, impressions by position band, impressions by country, the earning ratio (how many indexed URLs produce a click at all), and query-to-page match. Everything else is decoration. Sessions and Domain Authority will not tell you what is wrong; these five will.
I know because they diagnosed my own site. Between mid-June and 3 September 2026, santoshpaudel.me earned 22 clicks from 4,553 impressions — a 0.48% click-through rate across roughly 390 indexed URLs. That is a bad number. What makes it useful is that the five metrics below say exactly which kind of bad it is.
The five metrics
| Metric | Where to find it | A bad reading looks like | What to do about it |
|---|---|---|---|
| Clicks per query | Search Console → Performance → Queries | Impressions in the hundreds, clicks at zero, across most rows | Stop measuring the site average. Sort by impressions, look only at the zero-click rows |
| Impressions by position band | Same report, add the Position column and bucket it | Most impressions sitting past position 30 | Ignore them. Position 30+ traffic does not respond to title tweaks — the page needs rebuilding or deleting |
| Impressions by country | Performance → Countries | One country supplying a large share of impressions and no clicks | Exclude it from your CTR maths before you draw any conclusion |
| Earning ratio | Pages report vs. Indexing report | 390 URLs indexed, a handful with any click | You have a publishing problem, not a ranking problem. Stop adding pages |
| Query-to-page match | Performance → Pages → pick a page → Queries | The page ranks for a query you never wrote it for | Rewrite the page around the query it actually catches, or accept it will never convert |
Nothing in that table needs a paid tool. All five come out of Search Console, free, with a fifteen-minute export.
What 22 clicks on 4,553 impressions actually says
The instinct is to read 0.48% as "my titles are bad". It is almost never that. Split the same number two ways and the real story falls out.
Split one: geography
Russia supplied 1,320 impressions and zero clicks — 29% of everything the site was shown for, contributing nothing. The United States supplied 970 impressions at an average position of 38.8, also zero clicks. Nepal supplied 74 impressions and 8 clicks: a 10.8% CTR at average position 9.2.
So 36% of my clicks came from 1.6% of my impressions. (That is my own arithmetic on the figures above.) The sitewide 0.48% is an average of one real audience and two sources of noise. Averaging them together produces a number that describes nothing and suggests no action.
Split two: position
Position 38.8 is not a ranking. It is page four. Nobody scrolls to page four, so a page sitting there generates impressions without any realistic chance of a click — Search Console counts an impression whenever your result is loaded on the results page a user reached, whether or not they ever saw it.
This is why "improve your CTR" is bad advice at position 38. CTR is only a meaningful lever inside roughly the top ten. Outside it, a zero-click row is telling you about relevance, not about your title tag.
Splitting my own posts the same way was the uncomfortable part. Posts about building things — Claude Code, Supabase, Vercel, shipping actual software — rank between positions 2.8 and 15.5. Posts titled "[industry] content marketing" rank between 46 and 81. Same author, same domain, same quarter, same effort. The difference is that one set contains something only I could write and the other is a paraphrase of what already ranks. This page, before I rewrote it, was in the second group: 34 impressions at position 46.9.
The diagnostic that matters: impressions rising, clicks flat
If you watch one shape, watch this one. Impressions climbing month over month while clicks stay flat is the most misread pattern in SEO, because the impressions line looks like progress on every dashboard ever built.
It is not progress. It means Google is finding your pages and testing them on queries where they lose. Rising impressions with flat clicks is Google telling you your content is topically adjacent to a query without being the best answer to it. The correct response is fewer, better pages — not celebrating the chart.
The failure mode in the other direction is just as common: flat impressions with flat clicks means you are not being indexed or not being considered at all, which is a technical problem, not an editorial one. I wrote up a canonical hostname bug that cost me three months of indexing — that is what that pattern looks like from the inside.
Two of the five metrics catch the first pattern early: impressions by position band tells you the growth is landing past position 30, and the earning ratio tells you it is spread across pages that have never produced a click. Both are visible within a month. I did not check either for a year.
Why the measurement bar moved in 2025
There is an external reason the old dashboards stopped working. Pew Research Center tracked 68,879 Google searches from 900 US adults in March 2025 and found that when an AI summary appeared, 8% of users clicked a traditional search result, against 15% when no summary was present. Clicks on the links inside the AI summary itself accounted for 1% of visits (Pew Research Center, 2025). AI summaries appeared on 18% of searches in their sample.
The practical consequence for measurement: impressions inflate relative to clicks for reasons that have nothing to do with your page. A falling CTR at constant position may now be the results page changing under you. Which is exactly why you measure CTR per query at a known position band, never as a site average.
Where those AI answers pull from is measurable too. Semrush analysed 230,000 prompts across ChatGPT Search, Google AI Mode and Perplexity over thirteen weeks from July to October 2025 and found Reddit and Wikipedia were the two most-cited domains, with Reddit's share of ChatGPT responses swinging from roughly 60% in early August to roughly 10% by mid-September (Semrush, 2025). A citation source that volatile is not something to build a measurement plan on. Your own Search Console export is.
Run the numbers yourself
Export Performance → Queries as CSV (Search Console hands you a zip with Queries.csv inside). This is stdlib Python, no dependencies, and it runs with no arguments on built-in sample rows so you can see the output shape first.
"""Read a Search Console CSV export and print the five readings that matter.
Usage: python gsc_triage.py Queries.csv
No file? It runs on the built-in sample rows so you can see the output shape.
"""
import csv, sys, io
BANDS = [(0, 10, "1-10 striking"), (10, 20, "11-20 close"),
(20, 50, "21-50 invisible"), (50, 1e9, "51+ noise")]
# Illustrative sample only. The first two rows are real numbers from my own
# export; the rest are invented to show the report shape. Use your own CSV.
SAMPLE = """Top queries,Clicks,Impressions,CTR,Position
seo measurement,0,34,0%,46.9
ga4 consultant,0,19,0%,59.0
claude code supabase admin panel,6,41,14.63%,2.8
digital marketing nepal,8,74,10.81%,9.2
example generic industry query,0,212,0%,71.4
"""
def num(s):
return float(str(s).replace("%", "").replace(",", "").strip() or 0)
def load(path=None):
fh = open(path, newline="", encoding="utf-8-sig") if path else io.StringIO(SAMPLE)
with fh as f:
rows = []
for r in csv.DictReader(f):
# GSC names the first column after the report: Top queries / Top pages / Country
key = next(iter(r))
rows.append({"q": r[key],
"clicks": int(num(r["Clicks"])),
"impr": int(num(r["Impressions"])),
"pos": num(r["Position"])})
return rows
def report(rows):
clicks = sum(r["clicks"] for r in rows)
impr = sum(r["impr"] for r in rows)
print(f"1. Site CTR {clicks}/{impr} = {100*clicks/impr:.2f}%")
print("2. Impressions by position band")
for lo, hi, label in BANDS:
band = [r for r in rows if lo <= r["pos"] < hi]
bi = sum(r["impr"] for r in band)
bc = sum(r["clicks"] for r in band)
share = 100 * bi / impr if impr else 0
print(f" {label:18} {bi:6} impr ({share:5.1f}%) {bc:4} clicks")
earning = [r for r in rows if r["clicks"] > 0]
print(f"3. Earning queries {len(earning)}/{len(rows)} "
f"({100*len(earning)/len(rows):.0f}%) produce every click")
print("4. Dead weight (>=30 impressions, 0 clicks)")
dead = sorted((r for r in rows if r["clicks"] == 0 and r["impr"] >= 30),
key=lambda r: -r["impr"])
for r in dead[:10]:
print(f" {r['impr']:6} impr pos {r['pos']:5.1f} {r['q']}")
print(f" -> {sum(r['impr'] for r in dead)} impressions, 0 clicks")
print("5. Rescue list (position 8-25, impressions, no clicks)")
for r in sorted((x for x in rows if 8 <= x["pos"] <= 25 and x["clicks"] == 0),
key=lambda r: -r["impr"])[:10]:
print(f" pos {r['pos']:5.1f} {r['impr']:5} impr {r['q']}")
if __name__ == "__main__":
report(load(sys.argv[1] if len(sys.argv) > 1 else None))
Reading the output
Metric 4 is the one to act on first. Every row it prints is a page Google is showing to people who do not want it. Metric 5 is the money list: position 8 to 25 with impressions and no clicks is a page one rewrite away from page one, which is a better use of a weekend than a new post.
If you want the same thing without the CSV round-trip, the Search Console API exposes identical data through searchanalytics.query — same fields, same limits, just automatable.
What these five deliberately leave out
Domain Authority, Trust Flow, and every other vendor score. Google does not use them. They are a tool's opinion about your site, sold back to you as a metric.
Organic sessions on their own. A session count with no query attached tells you a number went up. It cannot tell you which page or which query caused it, so it cannot tell you what to do next.
Backlink counts. I ranked 34 keywords in four months with no backlink outreach at all — here is what I actually did. Counting links I was not building would have been a metric with no lever attached.
Anything measured before the data exists. New pages take months to accumulate enough impressions to read. Check weekly in the first quarter and you will make decisions on noise — my honest answer on how long SEO takes covers the timeline properly.
The rule underneath all four: a metric earns its place only if a bad reading tells you what to change. If you cannot name the action, delete the chart. It is the same principle behind treating content as a system rather than a stream of posts.
FAQ
What is SEO measurement?
SEO measurement is tracking whether organic search sends you people who act, using data you can attribute to a specific query and page. In practice it means five Search Console readings: clicks per query, impressions by position band, impressions by country, the ratio of indexed pages that earn any click, and whether the queries a page ranks for match what it was written for.
What are the most important SEO metrics to track?
Clicks and impressions segmented by query, average position banded rather than averaged, click-through rate inside the top ten only, the earning ratio across your indexed URLs, and conversions from organic. Site-wide CTR, Domain Authority and total sessions are not on the list, because a bad reading on any of them does not tell you what to change.
Is SEO measurable?
Yes, more directly than most marketing. Search Console gives you the query, the page, the position, the impression and the click for free, with a lag of a couple of days. What is hard is attribution after the click — connecting an organic visit to revenue weeks later — not the search data itself.
How do you measure SEO in GA4?
GA4 handles the half Search Console cannot see: what people do after they land. Link your Search Console property to GA4, then use the Organic Search channel and look at engagement rate, conversions and landing page performance. Keep query-level analysis in Search Console — GA4 will not show you the query.
Why do my impressions go up but not my clicks?
Because Google is testing your pages on queries where they rank too low to be seen. Check the position band: if the new impressions sit past position 20, they will not convert into clicks no matter what you do to the title. The page is topically near the query without being the best answer to it.
Measuring a site that gets impressions and no clicks? I will pull your Search Console data apart the same way I pulled apart my own and tell you which pages are worth rescuing. See my services or get in touch.
Get the AI-SEO Content Checklist
A practical checklist for getting your own content cited by Google AI Overviews, ChatGPT, and Perplexity — not just ranked.
Browse all free guides →Run this on your own numbers
Keyword Seasonality Forecaster — free, no signup, runs in your browser.
Want to implement this with guidance?
Santosh helps founders turn insights like this into real systems.
External Resources
Further Reading & Tools
Google Search Central
Official Google documentation on indexing, ranking, and Core Web Vitals
Ahrefs Blog
In-depth SEO research, keyword strategy, and link-building studies
Moz Learn SEO
Comprehensive SEO learning hub covering technical and on-page fundamentals
Search Engine Journal
SEO news, algorithm updates, and strategy guides