Property overrides for flag evaluation

Property overrides let you provide person or group properties directly to PostHog for feature flag evaluation, instead of relying on properties stored on the server. This is useful when properties are set from a different client (like a backend service setting a property that your frontend needs immediately), or when multiple clients setting the same property could cause inconsistent flag evaluations.

Why use property overrides?

Property overrides are useful when:

  1. Properties are set elsewhere: Properties can come from different parts of your application, like a backend service or another client. Your frontend might not know if they have been processed. If several clients set the same property, the value in PostHog can change unexpectedly as updates arrive from various sources.

  2. Values are transient or context-specific: You might need to evaluate flags using values that shouldn't be saved on the person record. This includes session-specific context, derived values, or information you prefer not to retain.

  3. Testing and debugging: You can test flag behavior using specific property values. This way, you won't need to change the actual user's properties.

Property overrides bypass server-stored properties. They send properties directly with the flag evaluation request. This way, results are immediate and consistent.

Client-side SDKs

Client-side SDKs can automatically include device and environment properties in every feature flag evaluation request. This ensures flags targeting properties like browser, OS, or app version work correctly without waiting for server-side processing.

Automatic overrides

Client-side SDKs automatically cache properties from identify() and group() calls for use in flag evaluation. You don't need to do anything special for these to work. Client-side SDKs also include common device and environment properties by default. The methods below give you additional control when needed.

From identify calls

When you call identify() with person properties, those properties are automatically cached for flag evaluation. This means flags can use the properties immediately without waiting for server-side processing.

// Properties are automatically available for flag evaluation
posthog.identify('user-123', {
email: 'user@company.com',
plan: 'enterprise'
})
// This flag check can use 'plan' immediately
const showFeature = posthog.isFeatureEnabled('enterprise-feature')

From group calls

Similarly, when you call group() with group properties, those properties are cached for flag evaluation:

posthog.group('company', 'company-123', {
name: 'Acme Inc',
plan: 'enterprise'
})
// Group properties are available for flag evaluation
const showFeature = posthog.isFeatureEnabled('enterprise-companies-feature')

Default properties in the web SDK

By default, the web SDK sends initial session properties with flag requests:

PropertyDescription
$initial_referrerFirst referrer URL
$initial_referring_domainFirst referring domain
$initial_current_urlFirst page URL visited
$initial_hostFirst hostname
$initial_pathnameFirst URL pathname
$initial_utm_sourceFirst UTM source
$initial_utm_mediumFirst UTM medium
$initial_utm_campaignFirst UTM campaign
$initial_utm_contentFirst UTM content
$initial_utm_termFirst UTM term
$initial_gclidFirst Google Ads click ID
$initial_fbclidFirst Facebook click ID
$initial_msclkidFirst Microsoft click ID

Other campaign parameters (gad_source, mc_cid, dclid, gbraid, wbraid, twclid, li_fat_id, ttclid, rdt_cid, etc.) are also included with the $initial_ prefix when present in the first page URL.

Including browser and device properties

To include current browser and device properties (like $browser, $os, $device_type) with flag requests, use the setAllPersonProfilePropertiesAsPersonPropertiesForFlags customization.

Using npm:

JavaScript
import { setAllPersonProfilePropertiesAsPersonPropertiesForFlags } from 'posthog-js/lib/src/customizations'
// Call after PostHog is initialized
setAllPersonProfilePropertiesAsPersonPropertiesForFlags(posthog)

Using the snippet:

HTML
<script type="text/javascript" src="https://us.i.posthog.com/static/customizations.full.js"></script>
<script>
posthogCustomizations.setAllPersonProfilePropertiesAsPersonPropertiesForFlags(posthog)
</script>

This adds the following properties to flag requests:

PropertyDescription
$browserBrowser name (e.g., "Chrome", "Safari")
$browser_versionBrowser version
$osOperating system name (e.g., "Windows", "Mac OS X")
$os_versionOperating system version
$device_typeDevice type ("Desktop", "Mobile", "Tablet")
$current_urlCurrent page URL
$pathnameURL pathname
$referrerHTTP referrer
$referring_domainReferring domain
$screen_heightScreen height in pixels
$screen_widthScreen width in pixels
$viewport_heightBrowser viewport height
$viewport_widthBrowser viewport width
$raw_user_agentRaw user agent string
utm_source, utm_medium, etc.Current campaign parameters

Default properties in mobile SDKs

Mobile SDKs (React Native, iOS, and Android) include common device and app properties in every feature flag evaluation request. The setDefaultPersonProperties configuration option controls this behavior and defaults to true.

PropertyDescription
$app_versionApp version from bundle/package info
$app_buildApp build number
$app_namespaceApp bundle identifier/namespace
$osOperating system name ("macOS", "iOS", "iPadOS", "tvOS", "watchOS", "visionOS", "Android")
$os_versionOperating system version
$device_typeDevice type ("Mobile", "Tablet", "TV", "CarPlay", "Desktop", "Vision")
$libSDK identifier (e.g., "posthog-ios")
$lib_versionSDK version

Manual overrides with setPersonPropertiesForFlags

Use setPersonPropertiesForFlags() to explicitly set properties for flag evaluation. These properties are merged additively and persist in storage until you call resetPersonPropertiesForFlags() or reset().

// Set properties for flag evaluation
posthog.setPersonPropertiesForFlags({
plan: 'enterprise',
company_size: 'large'
})
// Properties persist across flag evaluations
const showFeature = posthog.isFeatureEnabled('enterprise-feature')

Note: Properties set with setPersonPropertiesForFlags() are additive. Each call merges new properties with existing ones rather than replacing them.

Controlling automatic flag reload

By default, calling setPersonPropertiesForFlags() triggers an automatic reload of feature flags. You can disable this if you plan to set multiple properties before reloading:

// Set properties without reloading
posthog.setPersonPropertiesForFlags({ plan: 'enterprise' }, false)
posthog.setPersonPropertiesForFlags({ company_size: 'large' }, false)
// Manually reload when ready
posthog.reloadFeatureFlags()

Resetting property overrides

To clear all manually set property overrides:

posthog.resetPersonPropertiesForFlags()

On mobile SDKs, this automatically triggers a feature flag reload. Pass false to reset without reloading. On web, flags are not automatically reloaded. Call reloadFeatureFlags() manually if needed.

Group property overrides

You can also override group properties for flag evaluation:

// Set group properties for flag evaluation
posthog.setGroupPropertiesForFlags({
company: {
plan: 'enterprise',
employee_count: 500
}
})
// Reset group properties for a specific group type
posthog.resetGroupPropertiesForFlags('company')
// Reset all group properties
posthog.resetGroupPropertiesForFlags()

Use case: Targeting by browser or device

Web example: Target Chrome users on desktop

First, enable browser properties using the customization (see Including browser and device properties above). Then:

  1. Create a feature flag in PostHog
  2. Add filter conditions: $browser equals Chrome AND $device_type equals Desktop
  3. The flag automatically matches Chrome desktop users

Mobile example: Target a specific app version

With setDefaultPersonProperties enabled (the default), you can target app versions without any additional code:

  1. Create a feature flag in PostHog
  2. Add a filter condition: $app_version equals 2.0.0
  3. The flag automatically matches users on version 2.0.0

GeoIP property overrides

PostHog's servers automatically derive GeoIP properties from the user's IP address for feature flag evaluation. This enables geolocation-based flags without any manual setup on client-side SDKs.

Properties included

PropertyDescription
$geoip_city_nameCity name
$geoip_country_nameCountry name
$geoip_country_codeTwo-letter country code
$geoip_continent_nameContinent name
$geoip_continent_codeContinent code
$geoip_postal_codePostal/ZIP code
$geoip_time_zoneTime zone

Use case: Geolocation targeting

Create a feature flag targeting users in specific countries:

  1. Create a feature flag in PostHog
  2. Add a filter condition: $geoip_country_code equals US
  3. The flag automatically matches users accessing from the United States

No additional configuration is required on the client side.

Server-side SDKs

Server-side SDKs handle property overrides differently. Instead of persistent session-based overrides, you pass properties directly when evaluating each flag.

const flagValue = await client.getFeatureFlag(
'feature-flag-key',
'user-distinct-id',
{
personProperties: {
plan: 'enterprise',
company_size: 'large'
},
groups: {
company: 'company-123'
},
groupProperties: {
company: {
plan: 'enterprise',
employee_count: 500
}
}
}
)

GeoIP on server-side

Server-side SDKs disable GeoIP by default. This is because PostHog derives GeoIP properties from the request's IP address, which for server-side requests is your server's IP rather than your user's.

For geolocation-based flags, evaluate them on the client side where the user's actual IP is available.

Community questions

Was this page useful?

Questions about this page? or post a community question.