2026-05-27 · 7 min read

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.

1 10 20 30 35 Feb 7 Mar 23 May 8 Feb 14 — changepoint avg position lower is better ↓
Average Google position for ganttchart.ai, Feb 7 – May 8, 2026. The Feb 14 changepoint is a 25-spot overnight improvement.

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:

PRMergedTitleSEO Score
#203Jan 29Change homepage to include new gantt chart editor0.70
#207Feb 12Add stripe subscription support, update faq, add settings page0.60
#198Jan 28Integrate new gantt editor (20K+ lines changed)0.30
#210Feb 13Add homepage video0.30
#199Jan 25Remove mention of jira feature0.30
#205Jan 30Uncap length limitations0.10
#208Feb 9Fix OpenPanel SDK integration0.10
#209Feb 13Add Export to Google Sheets button0.10
#200Jan 25Remove data connections page0.10
#211Feb 13Add Sentry SDK0.00
#204Jan 30Start using AnannasAI as LLM provider0.00
#202Jan 29Add OpenPanel analytics tracking0.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.

100 75 50 25 0.5 threshold 74 0–.1 93 .1–.2 0 .2–.3 37 .3–.4 0 .4–.5 0 .5–.6 11 .6–.7 0 .7–.8 14 .8–.9 2 .9–1 PRs SEO relevance score → 88% below 0.5
SEO relevance score distribution across 231 of our merged PRs. 204 (88%) scored below 0.5; only 27 scored above.

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.

[ From the team building this ]

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 free