← Back to Blog
SEO StrategySEOPython

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.

SPSantosh Paudel· April 12, 2026· 9 min read· 503 views
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

MetricWhere to find itA bad reading looks likeWhat to do about it
Clicks per querySearch Console → Performance → QueriesImpressions in the hundreds, clicks at zero, across most rowsStop measuring the site average. Sort by impressions, look only at the zero-click rows
Impressions by position bandSame report, add the Position column and bucket itMost impressions sitting past position 30Ignore them. Position 30+ traffic does not respond to title tweaks — the page needs rebuilding or deleting
Impressions by countryPerformance → CountriesOne country supplying a large share of impressions and no clicksExclude it from your CTR maths before you draw any conclusion
Earning ratioPages report vs. Indexing report390 URLs indexed, a handful with any clickYou have a publishing problem, not a ranking problem. Stop adding pages
Query-to-page matchPerformance → Pages → pick a page → QueriesThe page ranks for a query you never wrote it forRewrite 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.

Free resource

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.

No spam. Unsubscribe anytime.

Browse all free guides →

Run this on your own numbers

Keyword Seasonality Forecaster — free, no signup, runs in your browser.

Open the calculator →

Want to implement this with guidance?

Santosh helps founders turn insights like this into real systems.

SEO Content Strategy

External Resources

Further Reading & Tools

Related Posts

01
14 min
SEO StrategyContent Strategy
TodaySEO Strategy

Perplexity freshness and the publishing cadence maths

What is actually published about freshness in AI citations, where the two biggest datasets disagree, and the arithmetic for when refreshing an old page beats writing a new one.

Read article
02
15 min
SEOSEO Strategy
TodayTechnical

Schema for AI Agents: What Actually Gets Parsed

I ship nine schema types on this site. Six are documented rich results in Google's gallery, five earn nothing here, and the published tests say AI assistants read JSON-LD as plain text rather than parsing it. Here is the actual markup and what each type earns.

Read article
03
14 min
SEOSEO Strategy
TodayAnalytics & Data Marketing

Which Keywords Have You Already Lost to AI Overviews?

Impressions holding while CTR collapses is the AI Overview footprint. Here is the BigQuery query, a standard-library Python triage script, and what happened when I ran the same test against my own 4,553 impressions and 22 clicks.

Read article