Skip to content
Chapter 93Lesson 2

When PostHog earns its weight

The decision of when product analytics with PostHog is worth adopting, framing events, feature flags, session replay, and experiments as four needs that take you past plain traffic analytics.

The marketing site already has Vercel Web Analytics on it. Traffic is flowing, you can see which pages people land on, and Core Web Vitals are green. That floor shipped last lesson, and for a while it’s the whole stack.

Then three asks land in the same week, from three different people:

  • Product: “Did the new onboarding flow improve trial-to-paid conversion?”
  • Engineering: “Let’s roll the new billing UI out to 10% of orgs first, before everyone.”
  • Support: “Three users say the dashboard just broke this week. No console error, every log is a clean 200. What happened on their screens?”

None of these questions is answerable from Vercel Web Analytics. That floor counts visits and measures how fast pages load. It doesn’t know who a given user is, what they did across several sessions, which version of a feature they saw, or what their screen looked like the moment it broke. Those are different questions, and they need a different tool.

This lesson doesn’t wire that tool up; the next one does. This lesson is about the decision: what the exact threshold past the cookieless floor is, which platform you reach for when you cross it, and why you reach for one platform instead of four. By the end you’ll be able to name that threshold precisely and decide “PostHog, or not yet?” on a real product, rather than adopting it just because every SaaS seems to have it.

Last lesson framed the floor’s edge as five signals: when you need to know who a user is, what they did, across sessions, gated by a flag, or in replay. That’s the right instinct, but it’s easier to act on if you collapse it into the four concrete product needs a team actually budgets for. The first two signals, “what they did” and “across sessions,” are really one need wearing two hats, so five becomes four. Each of these is a real line item on its own, and each maps to one of those three asks above, plus one more.

1. Event-level analytics. This is the one that answers what users do across sessions. Not “how many people visited” but “of the people who started onboarding, how many finished step two, and how many of those upgraded a week later.” You record an event for each meaningful action and attach properties to it, like plan: 'pro' or org_seats: 12, so you can slice the data later. From those events you build a funnel to see where people leak out, group users into a cohort , and chart retention to see who comes back. This is the need behind the product team’s onboarding question.

2. Feature flags. A flag is a switch you flip from a dashboard, without a deploy, to decide who sees what feature and when. You can roll a new feature out to 10% of orgs, kill a broken one instantly without shipping a revert, or turn something on only for users on the pro plan. Flags are also the substrate that A/B tests ride on top of. This is the need behind engineering’s “10% of orgs first” ask.

3. Session replay. This is a privacy-masked, video-like playback of what a user actually did in the browser: every click, scroll, and form interaction, with sensitive content blanked out. It answers what they did right before they bailed. It’s the tool for the UX bug that throws no error: the button that looks disabled, the modal that traps focus, the form that silently rejects valid input. Your logs are all 200s because nothing crashed; the user just got stuck. This is the need behind support’s “the dashboard broke with no error” ask.

4. Experiments. This is a statistical A/B test with a primary metric and an automated call on whether the difference is real or just noise. Not “I think variant B feels better” but “variant B lifted trial-to-paid by 4%, and here’s the confidence that it isn’t random.” It answers whether a change actually moved the metric. This is the disciplined version of the product team’s onboarding question, the one that survives a skeptical review.

Events

What do users do across sessions?

Example ask
Trial-to-paid funnel
Feature flags

Who sees what feature, when?

Example ask
Roll out to 10% of orgs
Session replay

What did they do before they bailed?

Example ask
The no-error dashboard bug
Experiments

Did this change move the metric?

Example ask
Did the new pricing copy lift upgrades?
Four needs, four questions. If your product has none of these, the cookieless floor is still the whole stack.

Notice the shape of every description above: it states what the need answers, not how the tool works. That’s deliberate. Each of these four gets its own lesson later: events and the identify pattern, then flags and experiments together, then replay. Right now the only skill that matters is recognizing which need is in front of you.

To make that boundary something you can apply on instinct, try it on a few cases. The hard part isn’t the obvious questions, it’s the borderline ones, where a question sounds like traffic but is really about identified behavior.

Sort each question by which tool answers it. A few are trickier than they look. Drag each item into the bucket it belongs to, then press Check.

Vercel answers this Traffic and Core Web Vitals, no identity
This needs PostHog Identity, behavior, flags, or replay
How many visitors did the pricing page get last week?
What’s the LCP on the dashboard route for real users?
Which countries does our traffic come from?
Did users who saw the new paywall copy upgrade more?
Roll the new editor out to 10% of pro orgs.
Why did this specific user rage-click and then leave?
What’s the trial-to-paid conversion funnel?
Which referrer sends the most signups?

That last one, “which referrer sends the most signups?”, is the trap. Raw referrer counts are traffic data, so Vercel answers it. But the moment the question becomes “which referrer sends signups that turn into paying customers,” you’ve crossed the line: now you’re tying an anonymous referrer to an identified user’s later conversion, across sessions, and only product analytics can stitch that together. The boundary isn’t the word “signup” or “referrer.” It’s whether the question can be answered without knowing who the user is and what they did over time.

Suppose you’ve got a real need, say events and flags, the two most products hit first. The naive next move is to go shopping, one tool per need. It’s worth walking that path deliberately, because it looks reasonable right up until it isn’t.

You’d pick an events tool (Mixpanel or Amplitude). Then a flags tool (LaunchDarkly or Statsig). When the replay need shows up, a replay tool (FullStory or Hotjar). When you start running experiments, an experiments tool (Statsig again, or Optimizely). Each one is best-in-class, and each one has a free tier. So what could go wrong?

Four things, and they compound:

  • Four contracts to evaluate, negotiate, and renew, which means four vendor relationships, four invoices, and four security reviews.
  • Four SDKs shipped into your client bundle. Every one is JavaScript the user’s browser downloads and runs before your app feels fast. The performance floor you just measured with Speed Insights starts sinking under the weight of your own analytics.
  • Four dashboards to context-switch between. The funnel lives in one tab, the flag lives in another, the replay in a third.
  • The last one quietly breaks everything: four identity models to keep aligned. The same user has a different ID in Mixpanel, in LaunchDarkly, and in FullStory. So the question you actually want to ask, “the users who saw variant B, did they finish the funnel, and can I watch one of them struggle?”, spans three tools that don’t share an identifier. Answering it means building and maintaining a join across three vendors’ export formats. Nobody does. The question just doesn’t get asked, and you paid four times for the privilege of not asking it.

That’s the cost. Here’s the resolution.

PostHog folds those four needs into one platform, one SDK, one identity, one dashboard. The four primitives, events, flags, replay, and experiments, all hang off the same identifier for a user. So “the users who saw variant B (a flag) completed the funnel (events), let me watch one struggle (replay)” is a single query against a single dataset, not a four-vendor join nobody maintains. The contrast is the whole argument.

Mixpanelevents+ own SDKidentity: ???
LaunchDarklyflags+ own SDKidentity: ???
FullStoryreplay+ own SDKidentity: ???
Statsigexperiments+ own SDKidentity: ???
Four contracts, four SDKs in the bundle, and four identity models. The cross-tool question needs a join nobody maintains.

A decision is only credible if you can name what you turned down and the exact condition that would have changed your mind. PostHog being the course default doesn’t mean the alternatives are bad; it means folding usually wins. Here’s each credible competitor and the one trigger under which you’d reach for it instead:

  • Mixpanel / Amplitude are the deepest event-analytics tooling there is, with no flags and no replay. Reach for one of these when event analytics is your only need and that depth genuinely outweighs having everything in one place, as it does for a data-heavy team whose entire job is funnels and cohorts.
  • Statsig has strong experiments and flags, weaker event UX, and replay that’s still maturing. Reach for it when experiments are the load-bearing daily primitive, where the team’s whole rhythm is “ship a test, read the result, ship the next test.”
  • LaunchDarkly is the flag specialist, with no events and no replay. Reach for it when flag scale outgrows PostHog’s flag UX: thousands of flags, complex targeting trees, enterprise governance and approval workflows.
  • Plausible / Fathom / June.so are privacy-first traffic analytics, the same tier as Vercel Web Analytics. They are not product analytics, and they don’t touch the four needs. Don’t let the word “analytics” fool you into reaching for one of these to answer a funnel question.

The default is PostHog because the typical SaaS has two to four of these needs at once, and once you have more than one, folding them onto a shared identity wins decisively. The alternatives stay in your back pocket for the day one of their specific triggers fires.

The cost shape, and why you don’t ship all four at once

Section titled “The cost shape, and why you don’t ship all four at once”

“Earns its weight” should have an actual number behind it, so let’s make the economics concrete.

PostHog bills per ingested event, per replay session, and per flag request , in volume tiers, and every primitive comes with a generous free allowance that resets each month, no credit card required. At the time of writing that’s roughly 1M product-analytics events, 5k session replays, and 1M feature-flag requests per month, comfortably more than a pre-PMF SaaS will touch. In practice it’s effectively free until you find product-market fit, then it scales per primitive as you grow.

The free tier being generous is exactly why the over-adoption trap is so easy to fall into. If it’s free, why not turn on all four primitives the day you sign up? Because “free to ingest” isn’t “free to maintain.” Every primitive you enable is something someone has to instrument, watch, and reason about. An event taxonomy nobody reads still rots, and replay you never watch is just disk space you aren’t using. The discipline is to adopt incrementally:

  • Pick the two primitives that earn their weight right now. For most products that’s events plus flags.
  • Add replay when a specific bug-class demands it, like the no-error UX bug or the rage-click report. Not before.
  • Reserve experiments for the metric-led moment, the first time someone asks “is this change real, statistically?” rather than “does this feel better?”

While you’re wiring those primitives in the next few lessons, three shapes can quietly burn through your quota, so they’re worth recognizing now to avoid writing them in:

  • A capture() call inside a React render. Every re-render fires another event, and React re-renders a lot.
  • A missing identity stitch, where the same real action gets recorded twice, once anonymous and once identified, because PostHog couldn’t tell they were the same person.
  • Recording every anonymous session on a high-traffic B2C site, which evaporates your replay quota on visitors who never even sign up.

Don’t worry about the fixes yet; the wiring lessons show the guardrails for each. For now, just know the traps exist so they don’t surprise you.

Section titled “PostHog Cloud EU, and the consent gate you’ll wire next”

Two decisions shape how you set PostHog up, and you have to make both now even though the wiring comes in the next lesson. Neither is code. Both are the kind of choice that’s far cheaper to get right at the start than to undo later.

PostHog Cloud comes in two regions. EU Cloud runs in Frankfurt and disables IP capture by default for new projects, which covers your data residency posture without a DPA dance. US Cloud is the equivalent for teams whose users are mostly outside the EU. There’s also a self-hosted, open-source PostHog, but operating it pulls in Postgres, Redis, Kafka, and ClickHouse , and the on-call cost of running that stack outweighs the savings for any team under tens of millions of events a month.

The course default is PostHog Cloud EU. Here’s the watch-out: picking US Cloud when your users are mostly in the EU is genuinely harder to undo than to set up right, because moving regions later means a data migration and a fresh project. The region is a load-bearing first decision. If your users are in the EU, choose EU now.

This is the constraint to carry into the next lesson, and it’s where the contrast with Vercel Analytics matters most.

PostHog handles personal data: distinct IDs (its identifier for one user or browser, the key every event, flag eval, and replay hangs off), IP addresses, and event properties that can carry user state. Under GDPR and ePrivacy, that makes it non-essential, which means nothing PostHog does is allowed to fire before the user actively accepts. You already built the machinery for this when you shipped the cookie consent gate: the app has a single source of truth, useConsent(), that exposes booleans for each category. PostHog reads one of them:

const { analytics } = useConsent();

Every PostHog call in this chapter routes through useConsent().analytics. When it’s false, nothing loads, and the SDK isn’t even imported. When it flips to true, the SDK is dynamically imported and capture begins. As a final safety floor, the SDK is also initialized with capturing opted out by default, so even if the gate is somehow bypassed, nothing leaks. The next lesson wires all of this; here it’s enough to hold the contract.

This is also a budget input, which loops back to the cost section: consented users are the only population PostHog ever sees. Your event volume is gated by your accept rate, not your total traffic.

Now keep this contrast straight, because it’s the most likely confusion between this chapter’s two lessons:

One more boundary while we’re naming complementary tools: PostHog does not replace Sentry. Sentry catches thrown errors, the exceptions and stack traces, the things that crash. PostHog captures behavior, including the bug-class that throws no error: the user who got stuck on a screen that worked perfectly as far as the code was concerned. You want both. They answer different halves of “something’s wrong.”

So that the next lesson isn’t a cold open, here’s a preview of what you’ll install. This is the only code in this lesson, and it’s a manifest: a list of what’s coming, not something to type yet.

Terminal window
pnpm add posthog-js posthog-node @posthog/next
  • posthog-js is the browser SDK. It captures events, evaluates flags on the client, and records session replay.
  • posthog-node is the server SDK. It captures events from server code and evaluates flags on the server, before a page even reaches the browser.
  • @posthog/next is the official App Router wrapper that ties the two together with Next.js conventions: a server-component provider that bootstraps SSR-evaluated flags, distinct-ID cookie seeding in middleware, a built-in same-origin proxy, and automatic event flushing.

That’s the whole manifest. The next lesson wires it end-to-end, through the consent gate and in the EU region, so the SDK only ever loads for users who’ve said yes.

Everything in this lesson collapses into a single procedure you can run on any future product. Walk it now, in the order an experienced engineer actually asks the questions: past the marketing-page stage first, then the four needs, then the verdict.

Do you reach past the cookieless floor?

Look at where those branches land: every “add PostHog” leaf converges on the same platform. That’s the one-platform argument restated as a picture. Reaching past the floor for any one of the four needs lands you on the platform that already covers all four, so you decide once, not four times, and the other three primitives are waiting for you when their moment comes.

The free-tier pricing numbers in this lesson move, so verify them yourself before you budget against them. PostHog’s own overview is also a good way to check whether the four primitives match what you actually need.