User and group targeting

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:

ModeWhen to use it
Properties (default)Target by user or group property filters. Each condition picks its own targeting type. Best for most flags.
DeviceStable 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:

TargetWhat gets bucketedWhen to use it
Users (default)Your distinct_idIn-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:

  1. Define your group types in PostHog (e.g., "company", "team", "project").
  2. Send .group() calls from your SDKs so PostHog knows which group each user belongs to.
// Associate the current user with a company
posthog.group('company', 'company_abc', {
name: 'Acme Inc',
industry: 'tech',
plan: 'enterprise'
})

Setting up a group-targeted condition

  1. Create or edit a feature flag.
  2. Under Release conditions, make sure Properties is selected as the top-level targeting mode.
  3. On any condition set, use the Target by dropdown to select your group type (e.g., "Companies").
  4. Optionally add property filters on group properties (e.g., plan equals enterprise).
  5. 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:

  1. PostHog checks each condition set in order.
  2. For a user-targeted condition, it hashes your distinct_id to determine rollout inclusion.
  3. For a group-targeted condition, it hashes the group key for the relevant group type.
  4. 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.

Missing group data causes conditions to be skipped

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 targetsAvailable property filters
UsersPerson 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():

Web
// 1. Identify the user
posthog.identify('user_123', {
email: 'jane@acme.com',
role: 'admin'
})
// 2. Associate them with a group
posthog.group('company', 'company_abc', {
name: 'Acme Inc',
plan: 'enterprise',
industry: 'tech'
})
// 3. Evaluate the flag — PostHog uses both user and group data
const showFeature = posthog.getFeatureFlag('mixed-rollout-flag')

Server-side SDKs

Server-side SDKs are stateless. Pass groups and groupProperties alongside personProperties when evaluating flags:

const flags = await posthog.evaluateFlags('user_123', {
personProperties: {
email: 'jane@acme.com',
role: 'admin',
},
groups: {
company: 'company_abc',
},
groupProperties: {
company: {
name: 'Acme Inc',
plan: 'enterprise',
industry: 'tech',
},
},
})
const flagValue = flags.getFlag('mixed-rollout-flag')

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.

ConditionTarget byFilterRollout
1Companiesindustry equals tech100%
2Users(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.

ConditionTarget byFilterRollout
1Companiesname equals Acme Inc100%
2Users(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.

ConditionTarget byFilterRollout
1Companiesplan equals enterprise100%
2UsersCohort: Beta testers100%

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.

Further reading

Community questions

Was this page useful?

Questions about this page? or post a community question.