> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.growthbook.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Targeting Conditions

> Define who sees a feature using attributes, conditions, and saved groups.

Add targeting conditions to a [rule](/features/rules) to control which values a user sees. Conditions are evaluated against **attributes** you pass into the SDK — like user ID, country, plan type, or any custom property.

This page covers how to set up attributes, write conditions, and use Saved Groups for reusable targeting.

## Attributes

For targeting to work, you need to pass attributes into the GrowthBook SDK and define them in the GrowthBook app. Here's a quick overview of how to do both.

### Passing Attributes into the SDK

Attributes are passed into your SDKs as key-value pairs. The keys are completely customizable — use whatever fits your application's data model.

Here's an example from the JavaScript SDK:

```ts theme={null}
growthbook.setAttributes({
  id: "123",
  email: "hello@growthbook.io",
  country: "US",
  url: window.location.href,
  userAgent: navigator.userAgent,
  admin: true,
  age: 50,
});
```

### Defining Attributes in GrowthBook

In addition to passing attributes into the SDK, define the same attribute keys in the GrowthBook app under **SDK Connections** → **Attributes**:

<Frame>
  <img src="https://mintcdn.com/growthbook-ea15456d/giSZyh24PfnTkKz4/static/images/features/edit-targeting-attributes-2.png?fit=max&auto=format&n=giSZyh24PfnTkKz4&q=85&s=fd886a5df2503f85f19518ba7f3d4c37" alt="List of targeting attributes" width="800" data-path="static/images/features/edit-targeting-attributes-2.png" />
</Frame>

<Info>
  **Attribute Values Are Never Sent to GrowthBook**

  The actual values of targeting attributes (e.g., user IDs, emails) are never sent to GrowthBook. They are only stored in memory locally within the SDK. This architecture keeps your users' PII safe and secure.
</Info>

Each attribute has 4 parts:

* **Attribute name** — How the attribute is referenced in the SDK.
* **Data Type** — The type of value the attribute holds.
* **Identifier** — Whether this attribute uniquely identifies a person, account, company, or device. Identifiers are used for experiment assignments.
* **Projects** — Which projects the attribute is available in. If no projects are selected, the attribute is available everywhere.

### Attribute Data Types

GrowthBook supports the following attribute data types:

| Data Type                   | Description                                            | Example                            |
| --------------------------- | ------------------------------------------------------ | ---------------------------------- |
| **Boolean**                 | true or false value                                    | `true`, `false`                    |
| **Number**                  | Floats or integers                                     | `25`, `3.14`, `-8`                 |
| **String**                  | Freeform text                                          | `"alice@example.com"`, `"blue"`    |
| **Enum**                    | Short list of predefined string values                 | `"basic"`, `"pro"`, `"enterprise"` |
| **Secure String**           | String values hashed before passing to SDK for privacy | `"secure-id-123"`                  |
| **Array of Strings**        | List of strings, useful for tags or categories         | `["admin", "editor"]`              |
| **Array of Numbers**        | List of numeric values                                 | `[1, 2, 3, 5, 8]`                  |
| **Array of Secure Strings** | Multiple hashed string values for secure targeting     | `["user123", "user456"]`           |

#### Constrained List Attributes

Array attributes (**Array of Strings**, **Array of Numbers**, **Array of Secure Strings**) can optionally be restricted to a fixed set of allowed values. When creating or editing an array attribute under **SDK Configurations → Attributes**, fill in the **Allowed Values** field with a comma-separated list — a user can still hold multiple values at once (e.g. `["admin", "editor"]`), but each must be one of the allowed values.

Once restricted, targeting conditions on that attribute use a typeahead multi-select that only accepts the allowed values (no free-form entry) and offer the `includes any of` / `includes none of` operators. Leave **Allowed Values** blank to keep the list unrestricted.

#### Changing an Attribute's Data Type

You can change an attribute's data type in place (including String → Enum) by editing it under **SDK Configurations → Attributes**. You do **not** need to create a new attribute or re-point features — the change is applied in place and existing targeting conditions keep evaluating, since values are stored as-is and the SDK does not enforce data types.

When converting to a constrained type (Enum, or an array with Allowed Values), make sure the allowed values include every value already used in existing conditions. Conditions that reference an out-of-list value, or that use an operator no longer offered for the new type, keep running but become harder to edit. The edit modal lists the features, experiments, and condition groups that reference the attribute so you can audit them first.

#### Semantic Version Targeting

GrowthBook supports semantic version string comparisons, so that `1.0.10` is correctly treated as greater than `1.0.9`.

To use this, create or edit a String attribute under **SDK Configurations** → **Attributes** and select **Version string** in the format dropdown.

<Frame>
  <img src="https://mintcdn.com/growthbook-ea15456d/1rsmujQCDzXz2Vho/static/images/features/targeting-semantic-versions-2.png?fit=max&auto=format&n=1rsmujQCDzXz2Vho&q=85&s=6e700cfd5e77d50e8b3393e7be8b90e4" alt="Version string attribute" width="800" data-path="static/images/features/targeting-semantic-versions-2.png" />
</Frame>

After saving, targeting operators (e.g., `is greater than`) automatically use a version-safe comparison function.

<Warning>
  **SDK Compatibility**

  Semantic version targeting is only supported in some SDKs. Check the release notes for your specific SDK to confirm compatibility.
</Warning>

#### Date Targeting

GrowthBook supports a date format for string attributes that makes it easier to target by date.

To use this, create or edit a string attribute under **SDK Configurations → Attributes** and select **Date string** in the format dropdown.

<Frame>
  <img src="https://mintcdn.com/growthbook-ea15456d/1rsmujQCDzXz2Vho/static/images/features/targeting-dates-2.png?fit=max&auto=format&n=1rsmujQCDzXz2Vho&q=85&s=642276dc5c3787c7e6a226caf778218b" alt="Date string attribute" width="800" data-path="static/images/features/targeting-dates-2.png" />
</Frame>

After saving, certain targeting operators (e.g., `is after or on` or `is equal to`) display a date picker input. Dates entered with the date picker are saved as ISO-formatted date strings (e.g., `2024-07-23T20:06`).

#### Country Code Targeting

Use [2-character ISO country codes](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) to simplify targeting by country.

To set up country code targeting:

* Create an attribute and set the **Data Type** to `String`.
* Change the **String Format** to `ISO Country Code (2 letter)`.
* Save the attribute.

When setting targeting rules, you'll get a dropdown to select a country directly.

<video autoPlay loop muted style={{width: '100%', height: "auto"}} controls allowFullScreen>
  <source src="https://mintlify.s3.us-west-1.amazonaws.com/growthbook-ea15456d/videos/feature-country-code.mp4" type="video/mp4" />
</video>

### Defining Conditions

GrowthBook provides a visual UI for defining targeting conditions using your attributes.

<Frame>
  <img src="https://mintcdn.com/growthbook-ea15456d/1rsmujQCDzXz2Vho/static/images/features/targeting-simple-2.png?fit=max&auto=format&n=1rsmujQCDzXz2Vho&q=85&s=6e6d373e84b680ba8c7c5b42fec07816" alt="Simple targeting conditions" width="800" data-path="static/images/features/targeting-simple-2.png" />
</Frame>

By default, string attributes are *case sensitive*. For example, if you pass `us` into the SDK, it will not match `US`. To make string attributes case insensitive, enable the **Case insensitive** toggle:

<Frame>
  <img src="https://mintcdn.com/growthbook-ea15456d/giSZyh24PfnTkKz4/static/images/features/feature-case-insensitive-toggle.png?fit=max&auto=format&n=giSZyh24PfnTkKz4&q=85&s=91a8cd776293c7907d9d44fc3ef43ac5" alt="Case insensitive toggle" width="800" data-path="static/images/features/feature-case-insensitive-toggle.png" />
</Frame>

### Advanced Mode

For more advanced targeting, enter conditions as JSON by clicking **Advanced Mode**.

The JSON structure uses a MongoDB-inspired query syntax. Multiple conditions are always joined with `AND` (except when explicitly using `$or`/`$nor`). Below are all supported operators with examples.

#### Simple Equality

Key/value pairs for exact matches:

```json theme={null}
{
  "attribute1": "value1",
  "attribute2": 123,
  "attribute3": false
}
```

#### Comparison Operators

Basic comparison operators for string/number attributes:

* `$eq` (equals)
* `$ne` (not equals)
* `$lt` (less than)
* `$lte` (less than or equal to)
* `$gt` (greater than)
* `$gte` (greater than or equal to)
* `$regex` (regular expression match, string attributes only)
* `$in` (in array)
* `$nin` (not in array)

```json theme={null}
{
  "foo": {
    "$gt": 10,
    "$lte": 99
  },
  "bar": {
    "$in": ["a","b","c"]
  },
  "baz": {
    "$regex": "^test-([0-9]+)$"
  }
}
```

#### Semantic Version Operators

Comparison operators for semantic version strings:

* `$veq` (equals)
* `$vne` (not equals)
* `$vlt` (less than)
* `$vlte` (less than or equal to)
* `$vgt` (greater than)
* `$vgte` (greater than or equal to)

```json theme={null}
{
  "appVersion": {
    "$vgt": "1.5.6",
    "$vlte": "5.4.0"
  }
}
```

#### Array Operators

Operators for array attributes:

* `$elemMatch` (at least one element must match the specified condition)
* `$all` (all of the specified values must exist in the array)
* `$size` (array length must match the specified condition)

```json theme={null}
{
  "emails": {
    "$elemMatch": {
      "$regex": "@gmail.com$"
    }
  },
  "hobbies": {
    "$all": ["hiking","tennis","chess"]
  },
  "tags": {
    "$size": {
      "$gt": 5
    }
  }
}
```

#### Miscellaneous Operators

* `$exists` (tests if the attribute value is null or not)
* `$type` (tests if the attribute's type matches the type specified)
* `$not` (inverts a nested condition)

```json theme={null}
{
  "alternateEmail": {
    "$exists": true
  },
  "foo": {
    "$type": "string"
  },
  "name": {
    "$not": {
      "$regex": "^J"
    }
  }
}
```

#### Logical Operators

Logical operators with arbitrary nesting levels:

* `$or`
* `$nor`
* `$and`
* `$not`

```json theme={null}
{
  "$or": [
    {
      "$not": {
        "foo": "abc"
      }
    },
    {
      "$and": [
        {"bar": true},
        {"baz": 123}
      ]
    }
  ]
}
```

<Info>
  **MongoDB-style Query Syntax**

  GrowthBook uses MongoDB query syntax because it is easy to read, write, and well documented. Conditions are never executed against a database — the SDKs include a lightweight interpreter for this syntax that runs entirely locally.
</Info>

## Saved Groups

<iframe style={{width: "100%", height: "auto", aspectRatio: "16 / 9", marginBottom: "1rem"}} src="https://www.youtube.com/embed/YAfGx1OY1jM?si=cjAnZfAX8BhPEPrc" title="Advanced Targeting with Saved Groups" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerPolicy="strict-origin-when-cross-origin" allowFullScreen />

Saved Groups let you target the same group of users across multiple features and experiments. Define a group once and reuse it everywhere — for example, beta testers or high-value customers.

<Frame>
  <img src="https://mintcdn.com/growthbook-ea15456d/1rsmujQCDzXz2Vho/static/images/features/saved-groups-overview.png?fit=max&auto=format&n=1rsmujQCDzXz2Vho&q=85&s=e00002b2e157ce45ee4a58ab4dba64cc" alt="Saved groups overview" width="800" data-path="static/images/features/saved-groups-overview.png" />
</Frame>

### Condition Groups

Define targeting rules based on user attributes. For example, target users who are located in the US and on a mobile device.

<img src="https://mintcdn.com/growthbook-ea15456d/1rsmujQCDzXz2Vho/static/images/features/saved-groups-condition.png?fit=max&auto=format&n=1rsmujQCDzXz2Vho&q=85&s=906f34284d50a58af0e9ea3544605e94" alt="Saved groups condition, showing how to add a US user on a mobile device" width="3830" height="1720" data-path="static/images/features/saved-groups-condition.png" />

### ID Lists

Manually define targeted users via text input or by uploading a CSV. For example, create a beta testers group by uploading a CSV of user IDs.

<img src="https://mintcdn.com/growthbook-ea15456d/1rsmujQCDzXz2Vho/static/images/features/saved-groups-id-list.png?fit=max&auto=format&n=1rsmujQCDzXz2Vho&q=85&s=00a6b6cb0c8805b49f897d91bf0d0753" alt="Saved Group UI, focusing on adding an ID list" width="3830" height="1720" data-path="static/images/features/saved-groups-id-list.png" />

ID Lists are limited to 1 MB. Using multiple large ID Lists may impact performance as it increases the SDK payload. Keep ID Lists as concise as possible.

ID Lists accept the following attribute types: `string`, `secureString`, or `number`. For targeting other types of attributes, use [Condition Groups](#condition-groups).

<Tip>
  **Optimized ID lists**

  Enterprise users can use optimized ID lists to reduce payload size. Enable this feature by editing your SDK connection and toggling on **Pass ID Lists by reference**. If the toggle isn't visible, your SDK is not compatible with this feature.
</Tip>

For more advanced targeting based on the state of other feature flags, see [Prerequisite Features](/features/prerequisites).

***

<Note>
  **Legacy behavior for empty ID lists**

  Empty lists would previously be ignored in the SDK payloads, causing targeting conditions referencing those lists to always evaluate to true. ID Lists created after the behavior was changed properly use the empty list, so rules checking whether a value is in the list always evaluate to false. Lists created before the change preserve the old behavior so as not to break existing features.

  To make an ID list with the legacy behavior evaluate to false instead of true, add a single placeholder value such as "" or "\_" so that the list isn't empty.
</Note>
