Metric · SEO

What does keywords in top 10 measure, and how do you track it in Metabase?

Keywords in top 10 counts how many of your tracked keywords rank on page one at each snapshot. It's the visibility metric that survives averaging: a count only moves when a keyword crosses the boundary that changes click behavior, which makes it harder to fool than average position and easy to act on when read next to its striking-distance companion bucket.

TL;DR — Bucket rankings into top 3, top 10, and 11–20, count best position per keyword per snapshot, and hold the tracked set fixed — a growing tracker inflates the count without any ranking progress. The 11–20 bucket doubles as your work queue; a LAG() movers table shows what crossed the boundary each week.

What keywords in top 10 measures

Organic clicks concentrate on page one, and within it on the top three results — a keyword moving from position 14 to 8 changes real traffic in a way that 44 to 38 does not. Counting keywords per bucket measures exactly those consequential crossings: the top-10 count is your page-one footprint, the top-3 count is where the clicks actually are, and the 11–20 count is the striking-distance queue worth working next.

The count's integrity depends on two disciplines: deduplicate to the best position per keyword per snapshot (SERP data can surface several of your URLs for one query), and version the tracked keyword set so the count is comparable across time. With those held, the trend line reads cleanly — every step up is a keyword that actually crossed onto page one.

What data does it need?

  • A seo_keyword_positions table with keyword, target_domain, stat_date, position, and search_volume, one row per keyword per snapshot at best position.
  • A consistent snapshot cadence — daily or weekly — since the movers comparison depends on adjacent snapshots existing.
  • A versioned keyword set, with set changes annotated so count jumps can be attributed to tracking changes rather than rankings.

SQL patterns

Top 3 / top 10 / striking-distance counts by snapshot datePostgreSQL
SELECT
  stat_date,
  COUNT(*) FILTER (WHERE position <= 3) AS top_3,
  COUNT(*) FILTER (WHERE position <= 10) AS top_10,
  COUNT(*) FILTER (WHERE position BETWEEN 11 AND 20)
    AS striking_distance,
  COUNT(*) AS keywords_tracked
FROM seo_keyword_positions
WHERE target_domain = 'yourdomain.com'
  AND stat_date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY 1
ORDER BY 1;
Keywords that entered or left the top 10 since the last snapshotPostgreSQL
WITH ranked AS (
  SELECT
    keyword,
    stat_date,
    position,
    LAG(position) OVER (
      PARTITION BY keyword ORDER BY stat_date
    ) AS prev_position
  FROM seo_keyword_positions
  WHERE target_domain = 'yourdomain.com'
    AND stat_date >= CURRENT_DATE - INTERVAL '14 days'
)
SELECT
  keyword,
  prev_position,
  position,
  prev_position - position AS change
FROM ranked
WHERE stat_date = (SELECT MAX(stat_date) FROM ranked)
  AND prev_position IS NOT NULL
  AND (
    (position <= 10 AND prev_position > 10)
    OR (position > 10 AND prev_position <= 10)
  )
ORDER BY change DESC;

Pitfalls

Growing the tracked set and calling it growth.→ Every keyword added to the tracker can only raise or hold the top-10 count — so an expanding set manufactures an up-and-to-the-right chart. Version the keyword set, chart keywords_tracked on the same card, and restate history when the set changes materially.
Counting every SERP appearance instead of best rank.→ When two of your URLs rank for one keyword, that's one keyword in the top 10, not two. Deduplicate to the best position per keyword per snapshot before bucketing, or sitelinks and multi-URL rankings will quietly inflate the count.
Ignoring search volume entirely.→ A raw count treats ten zero-volume wins as better than one head-term win. Keep the count as the trend metric — that's its job — but pair it with a volume-weighted view (weighted position or share of voice) so the team doesn't optimize for the easiest keywords instead of the ones that matter.
Mixing locations and devices into one count.→ Position 8 in the US and position 8 in Australia are different rankings for different searchers, and mobile and desktop SERPs diverge. Summing across segments double-counts keywords and hides regional losses — segment the count by search engine, location, and device, or fix one and say so.

Where this metric applies

Metrics

Dashboards

FAQ

Why count keywords in the top 10 instead of average position?
Because a count is robust where an average is fragile. Average position moves whenever the keyword set changes or long-tail rankings appear and disappear at the bottom; a top-10 count only moves when a keyword actually crosses the page-one boundary — the boundary that matters, since organic clicks concentrate overwhelmingly on the first page. It is the visibility trend that survives averages.
What position buckets are worth tracking?
Three buckets carry most of the signal: top 3 (where the majority of clicks land), positions 4–10 (page one, meaningful traffic), and 11–20 (striking distance — page two keywords that a content refresh or internal links can often push onto page one). The striking-distance bucket is the actionable one: it is a prioritized work queue, not just a report.
Does a growing top-10 count always mean progress?
Only if the tracked keyword set is stable. Add 200 keywords to the tracker and the top-10 count rises even if rankings went nowhere — the denominator grew, not the visibility. Version the keyword set, report the count alongside keywords_tracked, and consider a volume-weighted companion like share of voice so ten low-volume wins don't read the same as one head-term win.
Should the count use best position per keyword?
Yes — one row per keyword per snapshot, using the best-ranking URL. SERP-scraping sources can return several of your URLs for one keyword, and counting each appearance inflates the metric. Deduplicate to best position per keyword per date before bucketing, and keep devices and locations in separate series rather than letting one keyword count twice across segments.
How do you track keywords in the top 10 in Metabase?
Sync rank-tracker snapshots from SE Ranking, Ahrefs, or raw SERP data from DataForSEO into a SQL database, then chart bucket counts by snapshot date as a stacked area and add a week-over-week movers table using LAG(). Pin both to a keyword rank tracking dashboard next to your Search Console trend.