# Evaluation Cost Breakdown

The overall complexity of all rules in a gate determines feature gate evaluation speed. Each **condition**, **operator**, and **value count** contributes to a score that classifies rules and gates as Normal, Slow, or Very Slow. The gate complexity is the sum of the complexity of all its rules. A gate can be slow even without a single slow rule if the combined rules exceed the threshold. Use this page to identify the likely cause of a slow gate and the fastest way to fix it.

## How to interpret "Slow" and "Very Slow"

These labels are relative tiers, not fixed millisecond thresholds. Actual runtime depends on device or server, network, and whether the SDK is using the worst-case scenario (for example, even if country is included in the user object, the SDK assumes IP geolocation is required). These labels are warnings. If you're already using the best practice for your context, you can ignore them.

## Quick diagnosis

| What you see                                         | Likely cause                   | Fastest fix                                                                                                                                             |
| ---------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Gate targets OS/Browser/Version and is slow           | User-agent parsing at evaluation time | Pass `os_name`, `os_version`, `browser_name`, `browser_version` (server) or `systemName`, `systemVersion`, `browserName`, `browserVersion` (client) directly on `StatsigUser` |
| Gate targets Country and is slow                      | IP geolocation lookup          | Pass `country` directly on `StatsigUser`                                                                                                                 |
| Gate uses large ID lists (overrides or ID based segments) | Large list lookup              | Trim stale IDs, split lists, or move to conditional segments or a custom attribute                                                                  |
| Gate uses Regex or Version String operators           | Expensive per-check parsing    | Replace with exact matches or precomputed attributes                                                                                                     |
| Gate has many nested Passes Gate/Segment rules        | Costs compound across nested evaluations | Reduce nesting or push logic into a single gate/segment                                                                                                  |
| Conditions have many values (50+)                     | Large value scans              | Prune values, split cohorts, or move to a smaller segment                                                                                                |

## Cost drivers and fixes

### Conditions

Statsig applies evaluation costs based on the **condition type** used in a gate. This table lists only conditions with a significant impact. Conditions not listed don't significantly impact SDK evaluation speed.

| Condition       | Impact (assuming worst case) | worst case                | Reason                                                                       |
| --------------- | --------------------- | ---------------------------------- | ---------------------------------------------------------------------------- |
| BROWSER         | medium                | user agent                         | Requires user agent parsing unless you explicitly provide Browser            |
| BROWSER VERSION | medium                | user agent                         | Requires user agent parsing unless you explicitly provide Browser Version    |
| OS              | medium                | user agent                         | Requires user agent parsing unless you explicitly provide Operating System   |
| OS VERSION      | medium                | user agent                         | Requires user agent parsing unless you explicitly provide OS Version         |
| COUNTRY         | Low                   | IP lookup                          | Requires IP-based geolocation lookup when you don't explicitly set `country`     |
| PASSES SEGMENT  | high                  | deeply nested / large segment      | complexity dependent on cost of nested segments                              |
| FAILS SEGMENT   | high                  | deeply nested / large segment      | complexity dependent on cost of nested segments                              |
| PASSES GATE     | high                  | deeply nested with slow gates      | complexity dependent on cost of nested gates                                 |
| FAILS GATE      | high                  | deeply nested with slow gates      | complexity dependent on cost of nested gates                                 |

{% callout type="tip" %}
Tips:

* If you target OS/Browser or their versions, pass explicit values on `StatsigUser` to avoid user-agent parsing. Server SDKs support `os_name`, `os_version`, `browser_name`, and `browser_version`; client SDKs use `systemName`, `systemVersion`, `browserName`, and `browserVersion`.
* If you target Country, pass `country` directly to avoid IP-based lookup.
{% /callout %}

{% accordion title="Passes/Fails Segment and Gate conditions" %}
For conditions that depend on other gates or segments, the evaluation cost is directly related to the referenced entity. If a gate has a **Passes Gate** condition, the evaluation cost of the referenced gate propagates up to the base **Passes Gate** rule.
{% /accordion %}

### ID list size (overrides and ID based segments)

ID lists directly affect evaluation performance. This applies to both **ID list overrides** and **segment conditions** that reference ID lists.

| ID List Size | Impact    |
| ------------ | --------- |
| 1,000+ IDs   | High      |
| 10,000+ IDs  | Very High |

{% callout type="tip" %}
Tips:

* Trim stale IDs and scope lists to active cohorts.
* Split large lists into smaller, purpose-built cohorts.
{% /callout %}

### Operator

Statsig applies costs based on the **operator** used in a condition. Operators not listed don't significantly impact SDK evaluation speed.

| Operator                        | Impact | Reason                                  |
| ------------------------------- | ------ | --------------------------------------- |
| Any of (Case Sensitive)         | Low    | Requires explicit equality comparison   |
| None of (Case Sensitive)        | Low    | Requires explicit inequality comparison |
| Match Regex String              | Medium | Requires regex matching                 |
| Version String                  | Medium | Requires semantic version comparison    |
| Array Contains Any / None / All | Low    | Requires array scan                     |

{% callout type="tip" %}
Tips:

* **Match Regex String**: Replace with `ANY OF` or precompute a boolean/enum attribute.
* **Version String**: Precompute a normalized numeric value or `major`/`minor` fields and compare those instead.
* **Array Contains**: Keep arrays short and consider flattening frequent checks into a single boolean attribute.
{% /callout %}

### Value count

Statsig applies costs based on the **number of values** provided to a condition.

| Entity       | Impact |
| ------------ | ------ |
| 10–19 values | Low    |
| 20–29 values | Low    |
| 30–49 values | Medium |
| 50+ values   | High   |

{% callout type="tip" %}
Tips:

* If you're in the 50+ range, prune stale values or split cohorts.
* Consider moving large lists into a smaller inline segment or a custom attribute computed upstream.
{% /callout %}
