Case study: ganttchart.ai
A real changepoint. A 25-position overnight shift. And the one pull request, out of twelve candidates, that our system pointed at — before any of us thought to look.
On February 14, 2026, the average Google ranking for one of our apps moved from position 30 to position 2. Overnight.
We didn't notice for a month.
That's not because we don't pay attention. It's because the data lives in Google Search Console, the cause lives in GitHub, and connecting the two has always required a spreadsheet, a guess, and a lot of generous interpretation.
So we built a system to do it. And the first thing we did with it was run it on ourselves.
This is what it found.
The shift
The app is ganttchart.ai, a tool we run on the side. For the seven days before February 14, average position bounced between 23 and 33 — the bottom of page three on Google. On February 14, it dropped to 1.8. The next day, 7.8. The week after, it settled in the 2-to-5 range, where it has stayed for three months.
Something happened. We didn't know what.
The interesting part isn't the position move on its own. It's the secondary metric. On the same day position improved by ~25 spots, impressions dropped 95% — from 3,294 on February 9 to 165 on February 14 — while clicks held roughly flat.
That's a signature. Google narrowed the queries the site shows up for, and ranked it much higher on the now-tighter set. Something on the site became clearer to Google's index in a way it could reward.
But what?
We had four people on the project at the time. Asking each of them individually produced four different guesses. One thought it might be a Google update. Another wondered if a competitor had been penalized. A third pointed at a recent canonical-tag change. A fourth thought maybe a backlink from somewhere had passed authority. None of them had evidence.
This is the normal state of things for engineering teams who care about SEO. Something moves. Nobody is sure why. Everybody has a theory. The theory that wins is the one held by the most senior person in the room.
What our system said
Code Results does three things. It pulls Search Console history and runs CUSUM changepoint detection on the position series, so it identifies exactly when rankings shifted instead of just whether they did. It builds a counterfactual from the pre-shift trend, so the magnitude of the shift is measurable rather than visual. And it scores every merged PR for SEO relevance with an LLM, then weights those scores against the size and timing of each PR to attribute the changepoint to the most likely cause.
When we ran it on ganttchart.ai for the window leading up to February 14, twelve PRs were merged. Here is the ranked candidate list:
| PR | Merged | Title | SEO Score |
|---|---|---|---|
| #203 | Jan 29 | Change homepage to include new gantt chart editor | 0.70 |
| #207 | Feb 12 | Add stripe subscription support, update faq, add settings page | 0.60 |
| #198 | Jan 28 | Integrate new gantt editor (20K+ lines changed) | 0.30 |
| #210 | Feb 13 | Add homepage video | 0.30 |
| #199 | Jan 25 | Remove mention of jira feature | 0.30 |
| #205 | Jan 30 | Uncap length limitations | 0.10 |
| #208 | Feb 9 | Fix OpenPanel SDK integration | 0.10 |
| #209 | Feb 13 | Add Export to Google Sheets button | 0.10 |
| #200 | Jan 25 | Remove data connections page | 0.10 |
| #211 | Feb 13 | Add Sentry SDK | 0.00 |
| #204 | Jan 30 | Start using AnannasAI as LLM provider | 0.00 |
| #202 | Jan 29 | Add OpenPanel analytics tracking | 0.00 |
One PR stood out: PR #203. Highest SEO relevance score by a wide margin. Merged 16 days before the shift — exactly the lag we typically see between a deploy and a re-index.
The system's reasoning was specific: "The PR adds a new interactive Gantt chart editor section to the homepage, including new headings, content, and images with alt text, which directly affects user-facing page content and headings."
We hadn't told it to look for homepage changes. We hadn't told it that gantt-editor positioning was important. It read the diff and inferred all of that.
The PR
The PR is dull when an engineer reads it. It's a homepage update — new hero section, new screenshots, new copy below the fold. 332 lines added across 6 files. The kind of work that ships every other Wednesday at most companies and never gets retro'd because the bug count was zero and nothing broke.
But the diff changed three things Google cares about:
- The H1 and subheads on the homepage
- The image alt text on two new screenshots
- The body content describing what the product does
Before the PR, the homepage talked about gantt charts in general. After, it described a gantt chart editor — concrete, interactive, positioned around a specific search intent.
It took Google about two weeks to reindex and decide the new positioning was a sharper match for queries like gantt chart editor and interactive gantt. When it did, it narrowed the SERP it was showing us on (95% fewer impressions, on tighter intent) and raised the rankings on the queries it kept (~25 positions average). A near-textbook topic clarification.
We could not have told you, before running this analysis, that PR #203 was responsible. It was the seventh-largest PR in the window by lines changed. It wasn't tagged as SEO work in our internal tracker. The person who wrote it described it as "homepage update." Now we know it's the single most consequential thing our team shipped that quarter.
The 88%
While the system was up, we scored every one of our merged PRs for SEO relevance — across all four of our apps. The result was uncomfortable.
Of 231 PRs scored, only 27 — twelve percent — scored 0.5 or higher. The mean was 0.179. The median was lower.
Eighty-eight percent of the engineering work we ship doesn't measurably affect search. The testing, the refactoring, the infrastructure, the bug fixes, the configuration changes, the dependency upgrades, the analytics SDK wiring — all of it invisible to Google.
This isn't a problem. Most of that work has to happen for other reasons: reliability, velocity, technical debt, team sanity. The problem is that engineering leaders rarely have a way to tell which work matters for search and which doesn't. So they end up either crediting the wrong PRs (the loud ones, the visible ones, the ones tagged "growth") or hedging on everything: we shipped a lot this quarter and rankings went up.
Twelve percent of your PRs are doing the SEO work. You probably can't name them without doing exactly the analysis we just did.
Three things this generalizes to
We think these hold even at our sample size:
You have ranking changes you can't explain right now. Your average position is moving every week. Most of those moves are noise. Some are real. Without changepoint detection on your GSC data, you cannot tell them apart, and you cannot match the real ones to anything in your commit history.
Most of your engineering work is invisible to search — and that's fine, if you can tell which. The point of attribution isn't to make everyone do SEO work. It's to know which of your work is doing it, so you can plan the rest of the quarter against accurate information instead of a hunch.
Bundled PRs hide their own attribution. Look at PR #207 in the candidate table: it scored 0.60, second-highest. But it bundled FAQ copy updates inside a billing infrastructure PR. If that one had been the actual driver, we couldn't have cleanly attributed it. Isolated PRs aren't just better for code review; they're easier to learn from.
What this piece is and isn't
This is one case study, on one app, with one cleanly identifiable changepoint. We scored 231 PRs across four repos and ran the full causal pipeline on the one with the strongest signal. The sample is small. The conclusions about your specific situation should be soft until we — or someone else — does this at meaningfully larger scale.
We're running this analysis on beta customers' repos now. The follow-up to this piece, in a few months, will be the same write-up at five-to-ten times the scale.
If you want to see this kind of analysis on your own app, the Code Results beta is open.
See which of your PRs actually moved rankings.
Code Results connects your GitHub deploys to Google Search Console with causal attribution — so you stop guessing which code change moved organic search, and start measuring it.
Start for freeHow to tell if your last deploy hurt your SEO
Traffic dipped a few days after you shipped. Was it your deploy, a Google update, or the weekend? Read impressions, position, and clicks together — only one pattern points at your code — then rule out the short list of deploy-level regressions that actually tank rankings.
How long does it take Google to notice website changes?
Typically 3 days to 3 weeks — Google has to re-crawl, re-index, and re-rank, in that order. In the one deploy we measured end-to-end, rankings moved 16 days after the PR merged. Why the lag exists, what makes yours longer or shorter, and how to shorten the front of it.
Discovered – currently not indexed: what it means and how to fix it
Google knows your URL exists and has chosen not to fetch it. It is not an error, and on a small site it is almost never the "crawl budget" problem the guides tell you to fix — it is crawl demand. What the status actually means, why our own posts sat in it, and the structural fixes that ship in a pull request.