Realtime cohorts
Contents
Realtime cohorts are rolling out gradually and aren't switched on in most projects yet. If you'd like access, reach out to us in app. Behavior and limits on this page can change before general availability.
What is a realtime cohort?
A dynamic cohort is a list of people that PostHog rebuilds for you on a schedule. A realtime cohort is a dynamic cohort that PostHog also keeps up to date as events arrive, instead of waiting for the next rebuild.
It solves one problem. You can target a feature flag at a cohort built from events.
Cohorts built from person properties, like "email ends with @acme.com", have always worked in feature flags, because PostHog can check a person property while it evaluates the flag. Cohorts built from events, like "completed signed up in the last 30 days", have not. Answering "has this person done that?" means reading their event history, which is too slow to do on every flag request.
A realtime cohort answers the question in advance. PostHog keeps a record of who is in the cohort and updates it as events come in, so a flag only has to look it up.
What changes, and what doesn't
Realtime cohorts change feature flag targeting. Experiments and surveys pick their audience through feature flags, so they can target realtime cohorts too.
Everything else is unchanged. Insights, dashboards, and the person list and count on the cohort page still come from the standard cohort calculation, on its normal schedule.
Realtime cohorts are evaluated on PostHog's servers. A server-side SDK can't evaluate a flag that targets one locally. Checks of that flag fall back to a /flags request, and return no value if you have told the SDK to evaluate only locally.
Which cohorts qualify
PostHog works this out from the criteria you choose. There is no setting to turn on.
A cohort qualifies when every one of its criteria is one of these:
| Criteria | Example |
|---|---|
| Any person property criteria | email does not end with "@gmail.com" |
| Completed an event | Completed signed up in the last 30 days |
| Did not complete an event | Did not complete signed up in the last 30 days |
| Completed an event multiple times | Completed watched video at least 5 times in the last 2 weeks |
| Another cohort, if that cohort also qualifies | In cohort "Power users" |
You can narrow the event criteria by event property, such as completed purchase where plan equals "pro".
Three criteria negate: "Did not complete event", "Do not have the property", and "Not in cohort". Each one needs a criterion that isn't negated to bound it, either in the same group or in another group joined with "all". The cohort builder refuses to save a cohort that leaves a negation unbounded, or that puts one under "any", with the error "'Did not complete event' is a negative cohort criteria. Negation criteria can only be used when matching all criteria (AND), and must be accompanied by at least one positive matching criteria." Create the same cohort through the API and the save goes through, cohort_type still reads "realtime", but PostHog never builds its membership record, so a flag that targets it matches nobody.
A cohort whose only criterion is a reference to another cohort never becomes usable in a flag. Give it at least one person property or event criterion as well.
What stops a cohort qualifying
A single criterion from this list makes the whole cohort fall back to the standard calculation, and a feature flag can't use it:
- Sequences. Both "Completed a sequence of events" and "Did not complete a sequence of events".
- Lifecycle criteria. Every option under the "Lifecycle" heading in the cohort builder: completed an event for the first time, completed an event regularly, stopped doing an event, and started doing an event again.
- Actions. Event criteria have to name an event. Pointing the same criterion at an action isn't supported yet.
- The "First seen" person criterion, which reads when PostHog first saw the person rather than a person property.
- "Filter out internal and test users" turned on for the cohort.
- More than 20 million people in the cohort.
Static cohorts are never realtime. They don't change on their own, and they already work in feature flags.
Using a realtime cohort in a feature flag
- Create the cohort, or edit its criteria, as you normally would.
- Wait while PostHog works through the cohort's history. The errors below call this the backfill. However small the cohort, it takes about 20 minutes at the earliest, and longer for cohorts that look a long way back or match a lot of events.
- Add the cohort to a feature flag release condition.
If the flag won't save, the error tells you which step you're on:
- "Cohort 'X' is still being backfilled and cannot be used in feature flags yet" means step 2 hasn't finished. Wait and save again. If it doesn't clear, tell us.
- "Cohort 'X' has an event-based condition ... and cannot be used in feature flags" means either the cohort doesn't qualify, or realtime cohorts aren't switched on for the project. Compare its criteria against the list above first.
Editing a cohort a flag uses
While an active feature flag uses a cohort that has event criteria, you can't change that cohort's criteria at all, not even the person property ones. The save fails with "Behavioral filters cannot be added to cohorts used in feature flags."
This is on purpose. New criteria make the existing record wrong, and PostHog has to work through the history again before a flag can trust it. To make the change:
- Remove the cohort from every active flag that uses it.
- Edit and save the cohort.
- Wait for PostHog to work through the history again, then add the cohort back to the flags.
The same error blocks a rename from the cohort page, because saving there sends the criteria too. To rename a cohort a flag is using, PATCH only the name field through the cohorts API.
How up to date is it?
- People join and leave as their events arrive. Expect the change to reach feature flags in a minute or two.
- Time ranges expire on their own. Someone who matched "completed
signed upin the last 30 days" drops out once their last matching event is older than 30 days, even if they send nothing new. - The person count and person list on the cohort page are not realtime. They come from the standard calculation.
FAQ
How do I tell whether a cohort is realtime?
Fetch it from the cohorts API and read cohort_type. Qualifying cohorts have "cohort_type": "realtime". The field reads the criteria and nothing else. It doesn't tell you whether realtime cohorts are switched on for the project, or whether PostHog has finished working through the history, so saving the flag is still the test for both.
Do I still need the static cohort workaround?
Only in projects where realtime cohorts aren't switched on. There, duplicating a dynamic cohort as a static one is still the way to target people who completed an event.
Why did my cohort stop qualifying?
Either a criterion changed to one on the list above, or the cohort grew past 20 million people. Both send it back to the standard calculation. If this happens to a cohort a feature flag is already using, tell us so we can check the flag with you.