Year-over-year in Search Console sounds like a date-picker job. Pick this May and last May. Chart the two. Write the deck.
It fails on a calendar rule most people learn too late. Google documents that Search Console keeps Performance data for about 16 months. When a day ages out of that rolling window, it is gone from the UI and from the Search Analytics API. In month 17, the prior-year side of a YoY comparison is empty on Google's side. Plotting that hole as zero clicks reports a crash Google never measured.
This guide is the practical YoY playbook: when Google's window still supports the comparison, when it does not, how to avoid fabricated collapses, and what a hosted archive actually changes. The deeper retention math lives in Search Console's 16-month limit.
What "year-over-year" means in Search Console
People say YoY for three different jobs. Name which one you mean before you trust a chart.
- Property totals YoY — site clicks, impressions, CTR, and average position for the same calendar range this year vs last year. Headlines only. Use site totals (group by date), not a sum of query rows.
- Query or page YoY — the same named query or URL across both years. Only works for strings Google still lists in both periods. Anonymised rare queries never appear as rows in either year.
- Seasonal narrative YoY — "Black Friday this year vs last." Needs both periods fully published and present. A missing prior week is not a quiet prior week.
Search types stay separate. Web is not Discover. Discover and Google News have no query dimension and return position as null, not zero. Mixing types into one YoY line invents ranking drama that is really a feed mix.
When Google's window still supports YoY
On any given day, Google will still serve roughly the last 16 months, minus a 2–3 day publish lag. If both sides of your comparison sit inside that window, the UI and the API can answer without an archive.
| Comparison you want | Works in Google alone? | Why |
|---|---|---|
| Last 28 days vs the same 28 days ~12 months ago | Usually yes, if the property was verified then | Both ranges are typically still inside ~16 months |
| This calendar month vs the same month last year | Yes early in the year; fails later | Once "same month last year" ages past 16 months, the prior side empties |
| A May anniversary week when you are already in September+ the next year | No | That prior May is month 17 — outside the documented window |
| A property verified 4 months ago | Only vs those 4 months | Google never stored the earlier year. No tool invents it |
Use the date picker as a window, not as an open archive. If the prior range cannot be selected, or the API returns nothing for those dates, the comparison is incomplete. Do not fill the gap with zero.
Month 17: the empty prior year
Take a connect-or-check date of 28 September 2026.
- Sixteen calendar months earlier lands around 28 May 2025.
- The week of 18–24 May 2025 is older than that edge — outside the window.
- The week of 18–24 May 2026 is about four months old — inside.
Year-over-year for that May week is a real current week beside an empty prior week. The hole is on Google's side. Averaging the two, or treating the missing prior week as zero, fabricates a collapse.
The unpublished tail is a different hole, and it closes. The newest 2–3 days are often not final yet. SiteLine (and careful API jobs) re-import recent days because Google revises them. Days older than the 16-month edge do not come back on those refreshes.
Related calendar worked example: 16-month limit guide.
How to run YoY without lying to yourself
1. Headlines from site totals only
Group by date for property clicks and impressions. Do not sum query or page rows and call that the site. Anonymised queries stay in the chart and out of the table. On large days the UI export stops around 1,000 rows and the API page SiteLine stores stops at 25,000 — another reason table sums drift. Details: 1,000-row limit and how to export more than 1,000 rows.
2. Stop the range at published days
On a Wednesday, a complete comparison usually ends on Monday (sometimes Sunday). Including "today" because the picker allows it compares a full prior year with a stub. Prefer ranges that end on or before data_through when you use SiteLine MCP or the UI's finalized segment.
3. Never average a missing prior year into zero
Empty means outside the window or not yet published. Zero means Google counted no clicks. Those are different facts. Write "prior year not in Search Console's retained window" when the prior side is absent.
4. Recompute CTR and position correctly
- CTR = clicks ÷ impressions on the totals you named. It is a ratio (API stores 0–1; 0.04 is 4%). Do not average daily CTR columns.
- Position on the Performance chart is Google's property-level figure. Across a custom set of rows, use impression-weighted position:
sum(position × impressions) / sum(impressions).AVG(position)in a sheet is a different number.
5. Keep search types apart
Run Web YoY as Web. Run Image, Video, Discover, and Google News as their own series. Discover/News position stays null.
6. Query YoY is a named-string job
Only compare queries that appear in both periods. A query that dropped out of the named list may be anonymised, below the row cap, or truly gone — you cannot tell from silence alone. Say "of the queries we can see in both years."
What a CSV panic does not fix
Exporting the UI table the week before a day ages out does not give you a YoY archive.
- The download is about 1,000 representative rows, not every named query.
- Chart totals in that file can include data the table never lists.
- The file does not grow when Google revises the day.
- Sixteen months later Google will not re-serve the day so you can export again.
A spreadsheet is a working list. It is not a retention strategy. If you need month 17, you needed an API (or hosted) copy while Google still held the day.
Paths that can support real YoY after month 17
| Path | Prior year after month 17? | Notes |
|---|---|---|
| Search Console UI / API alone | No | Rolling ~16 months only |
| One-off UI CSV | No (incomplete even inside the window) | 1,000-row cap; no revision updates |
| Your own Search Analytics API warehouse | Yes, for days you pulled in time | You schedule pulls, storage, and rowLimit |
| BigQuery bulk export | Forward only from setup | No backfill of the 16 months already in GSC |
| Hosted archive (SiteLine) | Yes, for days imported while subscribed | Backfills what Google still holds on connect, then keeps new days |
BigQuery is strong for maximum row completeness going forward. It does not restore a prior May you never exported. SiteLine's connect job copies the overlap Google still serves that day (about 16 months minus publish lag, and only as long as the property has been verified), then keeps imported days while you subscribe. Cancel and reconnect later: you get whatever Google still holds on the new connect day — not the archive you dropped.
Honest product limits (same as elsewhere on this site):
- Up to 25,000 rows per day per report (one API page; not the second page to ~50k)
- Site totals stored separately so headlines are not invented from query rows
- Read-only
webmasters.readonly— no sitemap submits, no indexing requests - Plans from $4.99/mo; 7-day trial, no card
A YoY checklist you can paste into a brief
- Name the job: property totals, named query/URL, or seasonal narrative.
- Confirm both date ranges are fully published (end on or before the latest finalized day).
- Confirm both ranges exist in your data source (Google window vs your archive).
- Pull site totals for headlines; pull breakdowns only for named lists.
- Keep search types separate.
- Refuse zero-fill for missing prior periods.
- Weight position; compute CTR from totals; never sum query rows to rebuild the site.
- If agents read the data, require
data_from/data_throughand the same refusal rules (MCP setup).
When to connect an archive (and when not to bother)
Connect now if seasonal comparisons matter, if clients expect last-year Search Console in month 17, or if you are about to lose a quarter you still see in the UI today.
Do not expect miracles if the property is four months old, if you need a year Google already dropped before anyone copied it, or if you only wanted top queries for a slide (the UI export is enough for that).
Want the backfill Google still holds today, plus retention while you subscribe? Create a SiteLine account — trial starts without a card. Prefer agents to refuse empty YoY zeros for you? Sign up with MCP intent.
FAQ
Why does my YoY chart show a cliff last year?
Usually the prior range left the 16-month window, or you zero-filled missing days. Check whether those dates are still selectable in Search Console. If they are not, the cliff is retention, not demand.
Can Looker Studio or GA4 fill the prior Search Console year?
They can chart whatever Search Console still returns, or whatever you imported elsewhere. They do not extend Google's retention. Analytics visits are not impressions, position, or queries. Clicks vs sessions.
Does SiteLine invent last year's queries if I connect today?
No. Connect copies what Google still holds that day. Days already aged out are absent. Days imported earlier stay only while the subscription continues.
Should I compare query-level YoY every month?
Only for queries visible in both periods, and only after totals YoY. Named-query YoY without a totals baseline mixes anonymisation and row-cap noise into the story.
Is BigQuery enough for YoY?
For the future, yes if you turn it on in time and operate the warehouse. For the past 16 months already in Search Console, bulk export does not backfill. Pair it with an API or hosted backfill if you still need history Google has today.