Analyse a Search Console export without uploading it
Every Search Console analysis tool asks for one of two things: an OAuth grant giving it ongoing read access to your property, or a file upload putting your query data on someone else's server.
For a personal site, fine. For client data, an employer's property, or anything under a confidentiality agreement, both are a problem, and the problem is usually procedural rather than technical. You cannot get approval, so you do the analysis in a spreadsheet, badly, or not at all.
There is no technical reason for either requirement. A Search Console export is a handful of CSV files totalling a few megabytes. Everything worth computing from it is arithmetic that runs comfortably in a browser tab. This post is how to do that, and why the architecture is worth the small amount of extra work.
What the export actually contains
In Search Console, open Performance, set the date range as wide as it will go, and click Export → Download CSV. You get a zip containing:
Two constraints worth knowing before you build anything on this:
Queries.csv is capped at 1,000 rows. This is not a bug and there is no way around it in the UI export. It matters because your long tail, the part that usually holds the interesting findings, is truncated. Every total you compute from the query file is a total of the top thousand, not of your site, and any tool that does not say so is misleading you.
The columns are localised. The header is Top queries in some exports and Query in others, Top pages or Page, and CTR arrives as 12.34% in one locale and 12,34% in another. Anything that hardcodes English headers breaks silently on somebody else's export, it parses, finds no matching column, and reports zeros.
Handle both up front:
Parsing CSV without a library
You can read the files with the File API and parse them without a dependency. The only part that needs care is quoted fields containing commas, which query data has constantly.
Reading the dropped files is the standard drag-and-drop handler, with one detail: strip the UTF-8 byte-order mark. Search Console exports carry one, and it silently corrupts your first header key so Date becomes Date and every lookup misses.
That single character cost an afternoon.
The analyses worth running
Once parsed, everything is arithmetic. These are the ones that changed decisions, with the numbers they produced on a real 216-day dataset.
Concentration. What share of clicks comes from your top 1, 3, 5 and 10 pages. Result: 5 pages out of 159 produced 76.1% of all traffic, and 96 pages earned fewer than ten clicks in seven months. This is the single most useful number to compute first, because it tells you whether you have a channel or a dependency.
Brand vs non-brand. Split queries containing your name from everything else. Result: 44.1% of clicks were brand, at 16.02% CTR against 3.29% for everything else. One warning, from a real bug:
That bug is invisible on screen. Everything renders, the numbers are plausible, and every downstream section is wrong.
Your own position→CTR curve. Bucket rows by position and compute mean CTR per bucket. This is the one that makes the rest useful, because every published CTR table is an average across categories that behave nothing alike. On this dataset, the same site at position 4.82 in one country earned 32.93% CTR while at position 12.99 in another it earned 1.55%.
Striking distance. Queries at positions roughly 5–15 with real impression volume. Price each one against your curve to get an expected click gain. This is the cheapest work available, because the page already ranks.
Wasted visibility. High impressions, near-zero clicks. On this dataset one cluster returned 47,025 impressions and 102 clicks: 0.22% CTR at position 8.42. On a dashboard that highlights impressions this looks like a success.
Volatility. The standard deviation of daily clicks, so you know what a meaningless difference looks like. Here the day-to-day range was 187% of the mean.
The one function that is easy to get wrong
Pricing a position change against your curve looks trivial and has a subtle failure:
The original fell back to the last band. Every target of exactly 4 or exactly 10, which is every target anyone actually types, returned a gain of zero, and the tool looked like it was saying "not worth doing."
Why local-only is worth the constraint
The obvious benefit is that client data never leaves the machine, which turns a procurement conversation into no conversation.
The less obvious one is that it is verifiable. A privacy policy is a claim about intent. An architecture that never opens a socket is a claim you can check: load the page, disconnect from the network, drop the files, watch it work. That takes ten seconds and it is the difference between trusting someone and not needing to.
That verifiability turned out to be the single most link-earning property of the product this data came from. Every unpaid editorial link it earned cited the architecture, that files are processed locally and never transmitted. Not one cited the feature list. Sixty working tools earned nothing; one architectural decision earned everything.
There is a real cost, and it should be stated. You cannot do anything that genuinely needs a server: no scheduled monitoring, no cross-device history, no alerting, no fetching another origin. Those are real features and local-only forfeits them. The trade is worth making when the data is sensitive and the analysis is a one-off, which describes most Search Console work.
Run it yourself
Two ways, both from the same source code:
- In the browser: drop the unzipped folder, get all twenty analyses, export as Markdown or as a prompt for an AI agent.
- As a Node script: the toolkit includes a dependency-free CLI generated from the same library files, so the browser tool and the script cannot drift apart. That drift is not hypothetical: it happened once, and the two reported brand shares of 44.1% and 28.01% for the same data before the shared build step existed.
Questions
Can I analyse Search Console data without giving a tool API access?
Yes. The CSV export contains everything needed for the analyses in this post, and CSV parsing plus arithmetic runs fine in a browser tab. OAuth is required only for tools that need ongoing automated access, such as scheduled monitoring or alerting.
Why is Queries.csv limited to 1,000 rows?
That is the cap on the Search Console UI export. It matters because your long tail is truncated, so any total computed from that file is a total of your top thousand queries rather than of your site. The Search Console API returns more if you need completeness, but it requires an OAuth grant.
What breaks most often when parsing a GSC export?
Three things, in order: the UTF-8 byte-order mark corrupting the first header key; localised column names, so hardcoded English headers silently match nothing and report zeros; and locale number formats, where CTR arrives as 12,34% and parses as 12 or NaN.
Is browser-based analysis actually private, or just marketed that way?
You can verify it rather than trust it. Load the page, disconnect from the network, then drop your files. If the analysis completes, nothing was transmitted. That ten-second test is worth more than any privacy policy, and it is the reason to prefer architectures that permit it.
What should I compute first from an export?
Concentration, what share of clicks your top five pages produce. On the dataset in this post it was 76.1% from 5 of 159 pages. It takes one pass over the file and it reframes everything else you might do, because it tells you whether you are working on a channel or on a single point of failure.
Run this on your own data
- Search Console Analyzer: Drop your export, get a verdict
- SERP Audit: Paste a URL, get the fix list in priority order
- Schema Inventory: Which structured data is on which page
- Internal Link Graph: Which pages nothing points at
- OG Image Generator: And what it looks like once each platform crops it