PostHog

Everything Is an Event

July 26, 2026

The win for this lesson: you'll be able to look at any PostHog chart — a funnel, a retention grid, a traffic-sources table — and say exactly what it is counting. And you'll know the one thing that has to happen in Kobun's code before any of those charts can exist.

Analytics tools present themselves as a wall of dashboards, and the vocabulary arrives all at once: sessions, cohorts, funnels, retention, attribution. It looks like a dozen separate features to learn. It isn't. There is one table underneath, and every chart is a different question asked of it.

The table

PostHog stores a long, append-only list of things that happened. Each row is an event — PostHog's docs call it "the core unit of data". One row means: this happened, once, at this moment, and here is who did it.

You have seen this shape recently. Temporal's event history is the same idea: nothing is snapshotted, everything is a log of what occurred, and the useful answers are derived by reading the log. Analytics is that, for humans instead of workflows.

An event has four parts. Here is one from Kobun:

{
	"event": "post_publish",
	"distinct_id": "018daf23-89b3-7cf8-a4f1-94064c96df90",
	"timestamp": "2026-07-26T09:14:02.331Z",
	"properties": {
		"collection": "essays",
		"word_count": 1240,
		"is_first_publish": true,
		"$current_url": "https://app.kobun.dev/essays/new"
	}
}

That last point is the one worth slowing down on. post_publish on its own tells you a count. post_publish with collection and is_first_publish lets you ask whether people who publish essays behave differently from people who publish notes, and whether anyone ever gets past their first post. Same event. The properties did the work.

Who is "who"?

The distinct ID is a string, and before somebody logs in, PostHog has no idea who they are — so the browser SDK invents a random one and stamps it on their events. Those are anonymous events. They are stored, but no person profile exists for them yet.

When they sign up, your code calls identify with your real user ID. PostHog creates a person — its record of one human — and links the earlier anonymous activity from that session to it.

That single call is what turns two disconnected piles of data into one story. It is the mechanism behind the question you actually want answered: which of my blog posts brought in the people who went on to use Kobun? Without identify, the reader and the user are strangers to each other. (PostHog also recommends putting the marketing site and the app in the same project, for the same reason.)

Every chart is a query over that table

Now the jargon collapses. Each of these is the same rows, filtered and counted differently:

The questionThe chartWhat it actually counts
How many posts got published this month, and is it growing?TrendRows named post_publish, bucketed by day
Which collections do people publish into?Trend with a breakdownThe same rows, split by the collection property
How many people who start a post finish it?FunnelPeople with post_create, then post_publish, in that order
Do people who publish once come back and publish again?RetentionPeople with post_publish, checked for another one in later weeks
Where did this month's visitors come from?Web analyticsRows named $pageview, grouped by referrer

There is no separate "funnel data" or "retention data" being collected. There is one event stream, and a funnel is a particular way of interrogating it.

This also explains PostHog's two halves. Web analytics is a pre-built dashboard over a fixed handful of events — pageviews, page-leaves — with no custom insights. Product analytics is the open-ended half: any event you capture, any question you like. Same table, different amount of freedom.

The catch, and it is a real one

You can only ask questions about events you captured. There is no retroactive data. If Kobun never recorded which collection a post went into, that column does not exist for last month and never will.

Autocapture softens this on the web — PostHog will record clicks, pageviews, page-leaves and form submissions without you writing anything. What it cannot do is know what an action means in your product. "Clicked a button with class btn-primary" is not "published their first essay". Meaning is the part you have to write down in advance.

Which is why the next real decision isn't a technical one: it's choosing the short list of events that carry meaning in your product. That's lesson 3, and PostHog has an opinionated way in — pick the one number that represents your product working, then work backwards to the behaviour that drives it. (When you get there, names follow a convention: lowercase, snake case, present-tense verb, per PostHog's best practices.)

Check yourself

Answer from memory before scrolling back up. The effort is what makes it stick.

Question 1

Kobun has been capturing post_publish for a month, with no properties on it. You now want to know which collection each of last month’s posts went into. Can you?

Question 2

Somebody reads three of your blog posts over a week, then signs up for Kobun. What connects those three pageviews to their new account?

Question 3

You have a trend showing post_create counts and another showing post_publish counts. What can a funnel over those two events tell you that the pair of trends cannot?

Go deeper

Primary source: Getting HogPilled — PostHog's own opening guide. Read it now, while this is fresh. It skips the data model and goes straight to what to measure, so the two fit together neatly.

If you want the model itself in PostHog's words, Events and Persons are short and precise. Every term above is in the glossary.

Worth knowing: every source in RESOURCES.md so far is PostHog's own documentation. Good documentation, but a vendor describing its own category. Read the category claims with that in mind.

Next lesson: hands-on. Create the Cloud project, install PostHog on both a marketing site and the app it feeds — one project, deliberately — and watch these rows arrive in real time. Then read the pre-built web analytics dashboard and work out which events each tile is counting.


Anything unclear — what a "session" actually is, why the $ prefix matters, what happens if you call identify twice with different IDs — ask me. I'm your teacher for this course, and the follow-up questions are where the learning compounds.