The Analytics Were Mostly Me

The Analytics Were Mostly Me
Part of Building GribGrab — a series on what I learn building a weather app with Claude Code.
I added analytics to my weather app and felt great about it. The daily-users line mostly went up. Real people, checking real weather.
Then I looked at who they actually were.
The day that gave it away
One day stood out. Lots of “active users,” a nice tall bar. Then I removed my own visits — and nearly two-thirds of that day was one person. Me. On one device, reloading the app while testing a change to the chart.
63% of a “great” day was just me debugging.
It wasn’t a one-off. Over two weeks, my own testing was padding the average by roughly 18% — but unevenly. Almost nothing on a quiet day; a third or more on days I was deep in the code. That’s the trap: the noise is loudest on the days you work hardest, which are exactly the days you want the chart to mean something.
The numbers weren’t lying. I was just standing in them.
How I found this out: PostHog + Claude Code
Here’s the part I like. I didn’t click around a dashboard tool to work any of this out.
I use PostHog for analytics, and it has an MCP server — basically a way for Claude Code to talk to PostHog directly. So I stayed in my normal coding session and just described what I wanted, in plain English, and Claude Code did it for me:
- “Build me a dashboard for active users and retention.” → it created the dashboard.
- “Break daily users down by person and show me who loads the most.” → it ran the queries and showed me the data.
- “That top user is me. Add a filter that excludes my traffic from every chart.” → it built the exclusion and applied it everywhere.
No tab-switching, no learning a query language, no hunting through menus. I talked to my data like a coworker. Finding myself in the numbers, and then taking myself out, was a five-minute conversation in the terminal.
Why you’re worse than bots
Everyone knows to filter out bots, and analytics tools do it for you. But you — the person building the thing — are the heaviest user by far in the early days, and nothing flags you.
You load the app more than anyone. You reload after every deploy. You open it on your phone to check the mobile view. You leave a tab running that refreshes on its own. Every one of those gets counted. To the dashboard, you look like your most loyal fan.
One of my “users” had loaded a city 125 times in a single week from one device. That’s not a superfan. That’s me.
When you only have a handful of real users, one busy developer doesn’t bend the numbers. He is the numbers.
I thought I’d fixed this on day one
I wasn’t careless about it. From the very start I added a secret switch: open the site with ?internal in the address and it would turn analytics off for me.
It didn’t work the way I assumed. It muted exactly one page — the one I landed on. Click through to another city, or come back the next day, and it had already forgotten. It started counting me again the moment I did anything.
So for weeks I believed I was excluded, while I was quietly polluting my own data the whole time. A fix that half-works is worse than no fix, because it stops you from checking.
Finding myself for real
There’s no “this is the founder” flag, so I had to teach the system to recognise my own footprints. Three gave me away:
My own subdomain. I’d set up a separate web address — a sandbox — just for my own testing, so I can try things before they go live. That turned out to be the cleanest signal of all: anything coming from that address is me, full stop. No real user ever goes there.
My city and browser. My laptop shows up in my home city, on a browser almost nobody else in my numbers uses. That combination is basically always me.
The version I first showed up on. I was the only person using the app in its earliest builds — before I’d shown it to a single other person. So “first seen on a pre-launch version” is a clean tag for my own devices, including my phone, which the first two signals missed.
I handed those three rules to Claude Code, it turned them into an “internal traffic” group in PostHog, and pulled that group out of every chart. The growth lines barely moved. But the engagement lines — my “power users,” my regulars — shrank hard once I was gone. That’s the part that stung.
The real fix: don’t record it at all
A filter cleans up the dashboard, but the junk is still in the database, and I’d have to keep that filter current forever. Better to never collect it.
So now the app simply refuses to count me when it’s obviously me:
// Don't track my own testing.
if (
location.hostname === 'localhost' ||
location.host.includes('sandbox') ||
localStorage.getItem('internal') === '1'
) {
analytics.optOut();
}
My own computer and my sandbox subdomain opt out on their own. And for the live site, I visit once with ?internal — but this time the choice is remembered on that device, for good, instead of lasting a single page.
Two layers: the filter cleans up the past, the opt-out stops me being recorded in the future. One is mopping; the other is not spilling.
What changed
My dashboard finally shows strangers. I keep two versions of the users line side by side — with me and without me — so the gap between them is the first thing I see. When the two drift apart, I know I’ve just been busy, not popular.
The uncomfortable lesson: early analytics flatter you by default, because the person reading the numbers is the same person making most of them. You have to deliberately take yourself out to see anything true. Until you do, you’re not measuring your product. You’re measuring your own enthusiasm.
Takeaways
- In a young project, you — not bots — are the biggest source of fake data. Remove yourself before you trust a single number.
- Your traffic spikes on the days you work hardest, exactly the days you want to read as growth.
- A half-working fix is dangerous. My day-one
?internalswitch only muted one page, so I felt safe while polluting everything. Make sure your fix holds across a whole session, not one click. - Give yourself an obvious tell. A separate subdomain for your own testing makes “is this me?” trivial to answer.
- Two layers beat one: a filter to clean the history, an opt-out to stop recording yourself going forward.
- If your tools have an MCP server, use it. I built the dashboard, found myself, and applied the filter by talking to PostHog through Claude Code — no UI, just plain English.
How much of your product’s “engagement” is really just you, hitting refresh? I didn’t know until I subtracted myself — and most of a good day disappeared. → gribgrab.com
Thanks for reading! If you'd like to share your thoughts send me an email.