Free tool · no account · runs in your browser

Did that content change actually work?

You rewrote a page. Traffic went up. So did everyone's, because it was September. Upload your Search Console export and tell us which pages you changed and when — we compare each one with untouched pages from your own data over the same calendar days, and tell you whether the change beat them or whether we honestly cannot tell.

Your file never leaves your browser. It is read by JavaScript in this tab: there is no upload, no signup, no email, no model calls, and no limit on how often you run it. This page's security policy blocks fetch, XHR, WebSocket, EventSource and beacon calls and form posts from this window.

In Search Console, open Performance → Search results. Click the date button, choose Compare, and set the later range to start on the day you published and the earlier one to end the day before — then press Export → Download CSV and upload the ZIP, or the Pages.csv inside it. You can drop files here.

Check the order once it has run. The file does not say which of your two ranges you meant as the “after”, so the tool reads the first pair of columns as the later period and the second as the earlier, and prints both column headings directly under the headline. If they are the wrong way round every verdict is reversed — a page that fell reads as one that worked — so look at them before you act on the answer.

Compare is the part that matters. Without it the export gives each page a single total, and a before and an after cannot be read out of one column of numbers — so an export you have already downloaded needs taking again with Compare selected rather than uploading. Better still is a day-by-day table with a Date column and a Page column. It lets the tool choose comparison pages that behaved like yours in the weeks before the change, decide which pages qualify on days kept apart from the days the lift is measured over, and warn you if your page was already moving differently before the change. It needs the 56 days before each change and the 28 days after it. A Compare export has no such stretch, so the tool uses every other page and says so; the decay check lists the three places a day-by-day table comes from.

How big a file it takes. This page opens up to 64 MB of files at once and reads up to 12 MB of table text, which is about 135,000 rows of a day-by-day table. A ZIP counts at its compressed size against the first limit and at its unpacked size against the second. A file over either is refused by name and never read in part, and the refusal says what to trim: a shorter date range, or only the section you changed.

One change per line: the page URL, then the date you published it as YYYY-MM-DD, then optionally a note for yourself. Commas or tabs, so a column pasted out of a spreadsheet works. Up to 50 changes.

This tool needs JavaScript. If you can read this line, its script has not started: wait a moment, then reload; if it is still here, JavaScript is off or a script file failed to load.

What this actually does

The same estimator the paid ledger uses

Controls from your own site

Which pages qualify as comparison pages is decided from your own file, from each page’s own clicks on the days 56 to 29 before the change — a stretch kept apart from the days the lift is measured over — and how close each is in size is judged against your page’s clicks in the 28 days before the change. Nothing measured after the change is used, which would bias the answer towards whatever you were hoping for. When more than 8 qualify, the order among them also uses their trend over the 56 days before the change, which includes the days the lift is measured against; the method page says so too. A Compare export has no such stretch, so there every other page with at least 10 clicks across the two periods is used, and the result says so.

An interval, not a verdict

You get the lift as a percentage versus what the untouched pages predict, its 95% interval, the p-value and how many pages it rests on. The interval allows for the drift pages show on their own, so on a site whose pages wander it is wide, and "we cannot tell" comes with the smallest lift the measurement could have found. Widening it for that is how a tool avoids reporting noise as a win.

"We cannot tell" is an answer

If your file cannot support a claim — too few usable controls, no baseline traffic, a window the archive does not cover — that is what it says. A page with fewer than 10 clicks before the change gets a direction and no size, and one with none gets no measurement. A small number invented to fill the space is the failure this whole product exists to avoid.

What happens to your file

Nothing leaves your browser. The file is read by JavaScript running in this tab and analysed in memory; it is not uploaded, there is no copy on a server, and nothing from it is written to a cookie or to local storage (the theme switch remembers light or dark and nothing else). The page loads no analytics and no third-party scripts. Because nothing is sent, there is nothing for us to count or to limit: run it as often as you like.

You do not have to take our word for it. Open your browser's developer tools, choose the Network tab, run a check, and watch it make no request. Two things back that up. This page carries a content security policy, readable in its source, that blocks fetch, XHR, WebSocket, EventSource and beacon calls (connect-src 'none') and form posts from this window (form-action 'none'), and allows images only as inline data: URIs. A content security policy does not cover every browser feature. WebRTC is not covered, nor is navigating the tab to another address, and in one browser we tested a form that opens in a new window got past form-action. Nor does it stop this page asking penlid.com itself for a file (a stylesheet, a font, a script), because the page needs those: a request like that, with your data in its address, would reach our server's log. So the second check matters: the project's tests read this page's own script and every module it imports, and fail on any of the browser's network APIs, on navigation, and on any code that would build something for the browser to load — a form, an image, a link, a stylesheet — or set an address from script. A test that reads source text cannot catch code written to hide what it does, which is why the policy is the first check and these are the second.

The site-wide script penlid.js, which every page loads, contains network calls for the signed-in app's account switcher. This page never calls it, and a test checks that those calls sit only inside the switcher.

The two things that do leave this page's memory are the two you ask for: the text you click to copy, and the page you click to print or save as PDF.

One copy of the estimator. The estimate itself is computed by the same stats.js that the paid product's server imports, so the arithmetic you see here is the arithmetic the ledger runs, not a second copy that could drift from it. Reading your file and choosing the comparison pages are this tool's own code (gscsv.js and diagnose.js), and a test runs the paid evaluator and this tool on the same counts and requires the same stored row from both.

The other question, same file

If you want to know which of your pages are quietly losing ground rather than whether one specific change worked, the content decay check reads the same export and needs no change list.