User and group targeting
Contents
Feature flags evaluate against an entity to decide what value to return. By default, that entity is a user (identified by their distinct ID), but you can also target groups like organizations, companies, or teams. With per-condition targeting, you can combine both in a single flag — each condition set independently picks its own targeting type.
Top-level targeting mode
When creating or editing a feature flag, the Release conditions section shows two top-level options:
| Mode | When to use it |
|---|---|
| Properties (default) | Target by user or group property filters. Each condition picks its own targeting type. Best for most flags. |
| Device | Stable assignment per device. Good fit for anonymous users and experiments that span the pre-login to post-login transition. See device bucketing. |
Properties mode
Properties mode is the default. It evaluates conditions based on property filters and rollout percentages.
Within Properties mode, each condition set has its own Target by selector that controls which entity gets bucketed:
| Target | What gets bucketed | When to use it |
|---|---|---|
| Users (default) | Your distinct_id | In-app features for logged-in users |
| [Group type] (e.g. "Companies") | A group key (e.g., company_id) | Features that should be on or off for an entire organization, team, or other group type |
The Target by selector is visible on each condition set when your project has group types configured. If no group types are set up, all conditions target users by default.
Different conditions on the same flag can target different entity types. This lets you mix user-level and group-level conditions in a single flag without any additional configuration — just choose the target for each condition.
Group targeting
Group targeting evaluates a flag based on a group key instead of a user's distinct ID. Everyone in the same group sees the same flag value because PostHog hashes the group key, not the individual user.
For example, if you roll out a flag to 50% of organizations, PostHog hashes each organization's group key to decide whether it's in the rollout. All users in an included organization see the flag enabled, regardless of their own distinct ID.
Prerequisites
Group targeting requires group analytics. You need to:
- Define your group types in PostHog (e.g., "company", "team", "project").
- Send
.group()calls from your SDKs so PostHog knows which group each user belongs to.
Setting up a group-targeted condition
- Create or edit a feature flag.
- Under Release conditions, make sure Properties is selected as the top-level targeting mode.
- On any condition set, use the Target by dropdown to select your group type (e.g., "Companies").
- Optionally add property filters on group properties (e.g.,
planequalsenterprise). - Set your rollout percentage.
All users associated with a matching group see the same flag value. If a user belongs to multiple groups of the same type, the group key sent in the current SDK call determines the match.
Mixing user and group targeting
Because each condition set has its own Target by selector, you can freely combine user-level and group-level conditions in a single flag. No special configuration is needed — just set different targets per condition.
This is useful when you need a flag that accounts for both individual users and organizational membership. For example, you might want to enable a feature for all users in enterprise organizations, with a separate percentage rollout for everyone else.
How evaluation works
Condition sets are evaluated top to bottom and the first match wins:
- PostHog checks each condition set in order.
- For a user-targeted condition, it hashes your
distinct_idto determine rollout inclusion. - For a group-targeted condition, it hashes the group key for the relevant group type.
- The first condition set where all property filters pass and the entity falls within the rollout percentage is used.
User-targeted and group-targeted conditions hash different values, so their rollout distributions are independent. A 50% user rollout and a 50% group rollout don't overlap in any predictable way.
If a group-targeted condition requires a group type that the SDK call didn't include, that condition is silently skipped and evaluation continues to the next condition set. This means a misconfigured SDK call can cause users to unexpectedly match a later, less specific condition instead. Always verify that your SDK calls include the correct groups data. See sending user and group data from your SDKs for details.
Property filters
The properties available to filter on depend on the Target by selection of each condition set:
| Condition targets | Available property filters |
|---|---|
| Users | Person properties, cohorts, other flags |
| [Group type] (e.g. "Companies") | Group properties matching that condition's group type |
You can't filter on person properties in a group-targeted condition, and you can't filter on group properties in a user-targeted condition. This isn't just a UI constraint — group-targeted conditions hash on the group key and only have access to group properties at evaluation time. The PostHog UI enforces this to prevent incorrect configurations.
Sending user and group data from your SDKs
For flags with mixed user and group targeting conditions, your SDKs need to provide both user and group data in each flag evaluation call.
Client-side SDKs
Client-side SDKs automatically include the right data when you call identify() and group():
Server-side SDKs
Server-side SDKs are stateless. Pass groups and groupProperties alongside personProperties when evaluating flags:
If you omit groups or groupProperties, any group-targeted condition is skipped during evaluation.
Practical examples
Each example below uses a boolean flag. Mixed targeting also works with multivariate flags — the same evaluation rules apply, but the matched condition returns the assigned variant key instead of true.
Remember that user-targeted and group-targeted conditions have independent rollout distributions, so a 50% group rollout and a 25% user rollout don't interact with each other.
Roll out to tech companies, plus 25% of all other users
You want all organizations in the tech industry to get a feature, with a gradual rollout for everyone else.
| Condition | Target by | Filter | Rollout |
|---|---|---|---|
| 1 | Companies | industry equals tech | 100% |
| 2 | Users | (none) | 25% |
The group condition is checked first. If your company has industry set to tech, the flag is enabled. If the company doesn't match the filter, PostHog falls through to the user condition and includes 25% of all users. The same behavior applies if the SDK call didn't include a company group at all — the group condition is skipped and the user condition is evaluated instead.
Enable for a specific organization, plus 10% of all users
You want to guarantee access for one specific organization while running a broader rollout.
| Condition | Target by | Filter | Rollout |
|---|---|---|---|
| 1 | Companies | name equals Acme Inc | 100% |
| 2 | Users | (none) | 10% |
Everyone in Acme Inc gets the feature. For all other users, 10% are included based on their distinct ID.
Target enterprise organizations and individual beta testers
You want to enable a feature for organizations on the enterprise plan, and also for specific users who opted into a beta program.
| Condition | Target by | Filter | Rollout |
|---|---|---|---|
| 1 | Companies | plan equals enterprise | 100% |
| 2 | Users | Cohort: Beta testers | 100% |
Organizations on the enterprise plan get the feature for all their users. Individual beta testers also get it, regardless of their organization's plan. Users who aren't in either group don't see it.