How I Actually Decide What's Working: My Own Counters vs. GA4
Part of Making Money From a Small Site and Small Business Websites
By Paul Peery · August 3, 2026 · 3 min read

Ask a site owner how traffic is going and they'll open Google Analytics. Ask them whether they trust the number and you get a shrug — ad blockers eat some share of it, consent banners eat more, and the number that remains is sampled, modeled, and lives in someone else's warehouse.
I still run GA4. But every number I make decisions from comes out of my own database. Here's the split, and why I'd recommend it to anyone whose site is supposed to earn something.
Three small tables
The whole first-party layer is three tables, each embarrassingly simple — one row per thing per day, incremented in place:
Post views. Each post page fires a tiny beacon to my own endpoint, which bumps a (post, day) counter. It's rate-limited per visitor address so a refresh-happy reader doesn't inflate anything, and it only counts posts that are actually live. No cookies, no fingerprinting, nothing personal stored — a count is not surveillance.
Deal clicks. Every affiliate link on the site points at my own redirect — /go/deal-name — which increments a (deal, day) counter and then forwards to the merchant. This is the single highest-value trick in the whole setup, for a reason beyond counting: the destination URL lives in one database row, so when an affiliate program changes my link, I update one field and every post that ever mentioned that deal is correct instantly.
Traffic sources. When a view or a click lands, I also bump a (day, kind, source) counter — the referring site's hostname for views, or the internal page that sent a deal click. A utm_source on the URL wins over the referrer, and my own share buttons tag one per platform, so "came from the newsletter" vs "came from X" is my data, not Google's.
Why first-party wins as the source of truth
It counts everyone. Ad blockers don't block my own beacon on my own domain the way they block analytics scripts. The gap between GA4's number and the real one varies by audience — a tech-leaning readership blocks a lot — and you can't make revenue decisions on a number with an unknown discount applied.
It joins with money. This is the real reason. My intake form captures where each project request came from (the same utm/referrer logic). Payments live in the same database. So the dashboard can answer the only marketing question that matters — which source produces requests that turn into paid deposits — with a single join. GA4 can tell you a session count; it cannot tell you that the newsletter produced two clients and X produced none, because it never sees your payments table.
It survives. Analytics platforms deprecate, resegment, and reset (everyone who lived through the GA4 migration knows). Rows in my own Postgres are mine for as long as I keep them.
What GA4 and Vercel Analytics are still for
I keep both, deliberately, for what they're genuinely good at:
- Slicing pageviews by geography, device, and landing page without me building any of that.
- Event convenience — things like which newsletter-signup placement converts get fired as events and sliced in GA4's UI.
- Web-vitals field data from Vercel Analytics — real users' loading numbers, which no server-side counter can know.
The rule that keeps it sane: third-party analytics answer exploratory questions; first-party counters answer decision questions. If a number decides where I spend hours or dollars, it comes from my tables.
The honesty rule
One principle runs through all of it: never store a number you can't explain. My ad system counts "serves" — how many times a cached page render picked a banner — and the admin labels it exactly that, not "impressions," because a cached page is seen by many people and the counter genuinely doesn't know how many. A slightly humbler metric you fully understand beats an impressive one you'd have to caveat.
If you're building toward a site that earns, put the counters in on day one — they're a few dozen lines each, and the history only exists if you were collecting it. It's part of every build I do for client work, and the wider money-side experiments live under Making money from a small site.
Keep reading
All postsComments
No comments yet — be the first!
