Generate Report →

Unlocking Quick-Win Traffic: Striking Distance Keywords (4–20)

Position 11 earns roughly 1% CTR; position 8 earns about 3%. Moving three ranks triples clicks. How to find, score and fix the queries already close enough to win.

Most SEO effort goes into keywords a site does not rank for at all. The higher-return work is usually sitting untouched in Search Console: queries where you already appear on page one or just below it, accumulating impressions and almost no clicks.

The economics are simple. Click-through rate does not decline linearly with position — it collapses. As an order of magnitude, a query at position 11 earns around 1% CTR, the same query at position 8 around 3%, and at position 4 something closer to 8%. Your own numbers will differ; the ratio between them will not differ much. You are not chasing a 30% improvement by moving up a few ranks; you are chasing a multiple.

This is the workflow for finding those queries, scoring them so you work on the right ones, and applying the fix that actually corresponds to why each one is stuck.

Why three positions matter more than they sound

The table below is an illustrative decay curve, not a measurement. It exists to show the shape of the relationship and to give the scoring formula later in this article something to rank against. Real CTR varies enormously by query type, brand recognition, and SERP furniture, and the only curve worth trusting for your own decisions is the one you derive from your own Search Console data by bucketing your queries by average position and reading the actual CTR in each bucket.

PositionIllustrative CTRClicks at 2,000 impressions
127%540
311%220
56%120
83%60
111.1%22
150.6%12
200.3%6

The shape is the point. Moving a query from 11 to 8 roughly triples its clicks. Moving from 8 to 5 doubles them again. The same effort spent taking a position-2 query to position 1 yields a smaller absolute gain on most impression volumes.

One caveat compresses the whole curve: SERPs carrying an AI Overview push the organic results down the page and take a share of the clicks that would have reached them, so a position-6 ranking on an AI Overview query does not behave like a position-6 ranking on a clean SERP. Check whether your target queries trigger an AI Overview before projecting any gain — how AI summaries change click behaviour covers the measured effect and its primary source.

Extracting the candidate set

The Search Console UI can do this, but it caps at 1,000 rows and cannot combine filters the way you need. Set the date range to the last 90 days, open the Queries tab, and add two filters: position greater than 3.9, and position less than 20.1. Export.

For anything beyond a small site, use the API. This returns query and page together, which is essential — a query without its ranking URL is not actionable:

from googleapiclient.discovery import build
from google.oauth2 import service_account

creds = service_account.Credentials.from_service_account_file(
    'service-account.json',
    scopes=['https://www.googleapis.com/auth/webmasters.readonly'])
gsc = build('searchconsole', 'v1', credentials=creds)

body = {
    'startDate': '2026-04-24',
    'endDate': '2026-07-23',
    'dimensions': ['query', 'page'],
    'dimensionFilterGroups': [{
        'filters': [
            {'dimension': 'country', 'operator': 'equals', 'expression': 'usa'}
        ]
    }],
    'type': 'web',
    'rowLimit': 25000,
    'dataState': 'final'
}

rows = gsc.searchanalytics().query(
    siteUrl='sc-domain:example.com', body=body).execute().get('rows', [])

candidates = [
    r for r in rows
    if 4.0 <= r['position'] <= 20.0 and r['impressions'] >= 100
]

Three parameters deserve attention. dataState: 'final' excludes the most recent, incomplete days — leave it out and your position averages are polluted by partial data. The country filter is not optional if you serve multiple markets, because a global average position blends a rank of 4 in one country with 30 in another into a meaningless 17. And dimensions: ['query', 'page'] is what makes the output usable; querying by query alone tells you what is close but not what to edit.

Scoring so you work on the right twenty

Sorting by impressions puts high-volume, low-relevance queries at the top. Sorting by position puts trivial long-tail phrases there. The useful score estimates the clicks you would gain by reaching position 3:

# Replace these with CTR values measured from your own GSC data,
# bucketed by average position. The values below are placeholders
# that only set the relative weighting between positions.
CTR_CURVE = {1:0.27, 2:0.16, 3:0.11, 4:0.08, 5:0.06, 6:0.045,
             7:0.036, 8:0.030, 9:0.025, 10:0.021, 11:0.011,
             12:0.009, 13:0.008, 14:0.007, 15:0.006}

def opportunity(row):
    pos = min(15, max(1, round(row['position'])))
    gap = CTR_CURVE[3] - CTR_CURVE[pos]
    return row['impressions'] * max(0, gap)

ranked = sorted(candidates, key=opportunity, reverse=True)[:25]

Then apply two manual filters that no formula captures. Discard queries whose intent your page cannot honestly serve — a commercial-intent query landing on an informational post will not convert even if it ranks. And discard queries where the current top three are all brand-owned properties or Wikipedia, because the SERP has been decided by something other than content quality.

The remaining list is usually fifteen to twenty items, which is a realistic quarter of work.

Matching the fix to the actual cause

Striking-distance queries get stuck for distinguishable reasons, and applying the wrong remedy wastes the cycle.

The page never names the query. Most common by far. The page ranks on topical proximity alone, with the exact phrase appearing nowhere in the title, H1, or any H2. Fix: rewrite the title tag to lead with the query, and add an H2 phrased the way the query is phrased. It is the cheapest edit available and the one most likely to move a page that is already ranking on topic but never says the words. The heading-level mechanics are in restructuring H2 and H3 headings for search intent.

Position is fine, CTR is not. If a query sits at position 5 with a 1.2% CTR when the curve predicts 6%, ranking is not the problem — the snippet is. Rewrite the meta description with the query and a concrete number, and check whether a competitor is holding a rich result you could also earn.

Two of your own pages are splitting the query. Filter the API output by query and check whether more than one URL appears across the 90 days, or whether the ranking URL alternates. That is cannibalization, and adding content to either page makes it worse. Consolidate onto the stronger URL and redirect the weaker one instead.

The page genuinely under-answers. The query implies a subtopic the article covers in one sentence. Fix: add a dedicated 200–350 word section with its own H2, specific numbers, and a table if the query is comparative. This is slower but produces the most durable gains, and it is the same test information gain applies — whether the section says anything the ranking pages do not already say.

Intent mismatch. The query wants a comparison, a price, or a tool; your page is a general explainer. No amount of on-page tuning fixes this. Build a separate page and let the original keep its own queries.

Measuring honestly

Compare the 28 days after the change to the 28 days before, at query level, filtered to the same country and device. Anything shorter and you are reading noise; anything compared against the edit week itself is contaminated by recrawl volatility.

Watch three numbers per query: position, CTR, and impressions. The instructive combinations:

  • Position improves, CTR improves — the fix worked.
  • Position improves, CTR flat — you gained rank but the snippet is not compelling. Title and description work remains.
  • Position flat, CTR improves — the snippet rewrite worked without a ranking change. Still a real win.
  • Impressions rise sharply, position falls — you now rank for a broader, weaker query set. Usually harmless, occasionally a sign the page drifted off-intent.

Set the comparison up once as a saved report, or as a scheduled script against the same API call used above, rather than re-deriving it each time.

Start with five

Pull 90 days, filter to positions 4–20 with at least 100 impressions, score by the opportunity formula, and take the top five. For each, check one thing: does the exact query phrase appear in the title tag and in at least one H2 on the ranking URL?

Where the answer is no, fixing it is an hour of work and the outcome shows up in the next 28-day comparison window. That is the whole method — the rest is repetition and discipline about measurement. If you would rather have the full scored candidate list, cannibalization flags, and draft titles delivered rather than derived, that is the core of the Premium MarketLens audit.

Run this article on your site

Pull my last 90 days of Google Search Console data at query and page level, then filter to rows with average position between 4 and 20 and at least 100 impressions. Score each row by impressions multiplied by the CTR gap between its current position and position 3, sort descending, and give me the top 25. For each, tell me whether the ranking URL's title tag and H2 headings contain the exact query phrase, and draft a replacement title under 60 characters where they do not.

Paste into Claude Code, ChatGPT, Cursor or Gemini. It executes the steps above against your own site.

Frequently Asked Questions

What position range counts as striking distance?

Positions 4 to 20 is the practical window. Below position 4 you are competing for incremental CTR rather than a step change, and past position 20 the gap usually reflects a genuine authority or content deficit that on-page work alone will not close. The densest opportunity sits at positions 8 to 15, where a small ranking gain crosses the page-one boundary.

How many impressions does a query need before it is worth optimizing?

As a floor, 100 impressions over 90 days for a small site and 500 for a larger one. Below that the position figure is an unreliable average built from too few data points, and you cannot distinguish a genuine rank from a handful of personalised or geographically skewed results.

Why does Google Search Console show average position 9.4 when I rank 6 in my own searches?

The reported figure is a weighted average across every impression — all devices, countries, and personalisation states. Your own logged-in search from your own city is one of the most favourable data points possible. Always filter by country and device before trusting a position number for decision-making.

Should I create a new page or optimize the existing one?

Optimize the existing page when the query is a semantic variant the page already partly addresses. Build a new page only when the query has a distinctly different search intent, because publishing a near-duplicate against your own ranking URL creates cannibalization and typically drops both pages rather than lifting either.

How long before a striking-distance fix shows up in the data?

Title and meta description changes surface in 3 to 14 days once the page is recrawled. Content additions that target new subtopics take 4 to 8 weeks to stabilise. Compare a 28-day window after the change against the equivalent window before, not against the week of the edit, or seasonality will mislead you.

Continue the track — Data-Driven Content Strategy