Cohorts

Cohort analysis follows a set of entities over time — which is why a dataset needs both roles.entity and roles.time before a cohort can be built over it at all.

Cohort analysis follows a group of things over time: the customers who first ordered in March, the products introduced last quarter, the locations opened this year — and what happened to each group since.

It is the one feature in the studio with a hard requirement on how a dataset was declared.

What a cohort needs from your view

Two roles, both of them:

RoleWhy the cohort needs it
roles.entityThe key that identifies the thing being followed. Without it there is nothing to group into a cohort.
roles.timeThe axis the cohort is followed along, and what defines which cohort a row belongs to.

A dataset missing either role cannot be used for cohorts. Not "works badly" — unavailable. The type-based fallback that guesses measures and dimensions cannot produce an entity, because no column type says "this is the identity of the thing somebody wants to follow".

Two lines in your analytics.json are the difference:

analytics.json
"roles": {
  "entity": "location_id",
  "time": "created_at"
}

Choosing the entity

The entity is the identity of the thing being followed over time — which is not always the view's key.

ViewkeyUseful entity
One row per locationthe location idthe location id
One row per stock movementthe movement idthe product, or the location
One row per order linethe line idthe customer, or the product

The rule: ask what somebody would want to follow month over month. Following individual movements is meaningless; following the products those movements happened to is the analysis.

Use a stable id, not a label. An id that changes when somebody edits a name breaks a cohort silently, and — as Tenant isolation notes — an id is also the right choice when the alternative is exposing a person's name or email.

Choosing the time

The timestamp that answers "when did this happen", not "when did we last touch the row". A creation timestamp produces meaningful cohorts; an update timestamp produces cohorts of your own write pattern.

Cast it to timestamptz or date, and mark it "optional": false. A null in the time column is a row that belongs to no cohort at all, and nothing will tell the operator it was dropped.

What the operator does with it

They pick your dataset, define the cohort by a period of the time column, and read what the entity group did afterwards. Measures you declared are what they can quantify per cohort.

That is the extent of it in Cockpit today. There is no funnel builder, no retention-curve API, and no way to export a cohort on a schedule — see What does not exist yet. If a customer needs cohort analysis inside your own product, build it on your own store: the same two ideas, an entity key and an event-time axis, are all a cohort query needs. See Modelling.

Where to go next

Was this page helpful?