---
title: Monitor an Experiment
description: "Track health checks, exposures, and diagnostics for active experiments in Statsig Cloud."
product: general
lang: en
token_estimate: 3401
---
# Monitor an Experiment

Statsig runs health checks on every live experiment: SDK checks arriving, unit IDs matching, exposures balanced with no sample ratio mismatch (SRM), and no crossover units. Review the checks after you launch the experiment and again before you read its results. Use this page to find out whether assignment and logging are correct. To interpret metric lifts, go to [How to read experiment results](https://docs.statsig.com/experiments/interpreting-results/read-results). To clone, rename, archive, or otherwise operate on the experiment itself, go to [Manage an Experiment](https://docs.statsig.com/experiments/manage).

> For AI agents: a documentation index is available at [/llms.txt](/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

## Experiment health checks

1. Go to _Experimentation > Experiments_ and select the experiment you want to inspect.
2. In the _Details_ panel, find the health status badge next to the quality score, for example **Healthy** or **Unhealthy**.
3. Hover over the badge to see the _Experiment Health Check_ summary, then click **View Details**.

Alternately, open the _Diagnostics_ tab, which leads with the _Experiment Health Check_ section. A warning icon on the _Diagnostics_ tab label also signals a failing check. Select a check to read its status, such as _FAILED_, and an explanation of what triggered it.

The checks shown depend on the experiment's setup and how long it's been running. The console organizes each check by its current state. For example: _Checks not yet detected_ or _Pulse metrics available_. Common health checks include:

- **Checks detected**: Verifies that the SDK is reporting config checks shortly after launch. _Checks not detected recently_ means the experiment previously recorded exposures but none in the last 24 hours.
- **Valid unit type**: Confirms that checks include the experiment's configured ID type.
- **Event metrics have data**: Ensures that events carry the same unit ID as exposures. This lets Statsig compute metrics. This check often surfaces problems when downstream tooling, such as Segment, omits `stableID` or custom IDs.
- **Pulse metrics available**: Indicates that results are ready (typically the day after launch).
- **Exposures are balanced**: Runs a [chi-squared test](https://www.jmp.com/en/statistics-knowledge-portal/linear-models/chi-square-test) for sample ratio mismatch (SRM). Occasionally, warnings occur because of randomness, but persistent red alerts point to assignment or logging issues. Refer to [SRM thresholds](#srm-thresholds) for more information.
- **Crossover units detected**: Highlights units exposed to more than one group, when they exceed 0.1% of exposed units. Statsig Cloud keeps these units in both groups because the SDK rarely produces crossovers, and flags them so you can address the root cause. Refer to [Crossover troubleshooting](#crossover-troubleshooting).
- **Default value type mismatch**: Warns if an experiment's fallback default value type disagrees with the parameter definition.
- **Group Assignment Health**: Surfaces unexpected assignment reasons (for example, `Uninitialized` or `InvalidBootstrap`). Click **View Assignment Reasons** to see the hourly breakdown.
- **Differential Impact Detection**: Reports when Statsig has finished checking whether a group of users responds to the treatment differently from the rest. Refer to [Differential impact detection](https://docs.statsig.com/experiments/exploring-results/differential-impact-detection).

### SRM thresholds

The Exposures are balanced check sets its status from the chi-squared p-value and the absolute deviation from the expected split.

| p-value | Absolute deviation | Status |
| --- | --- | --- |
| Between 0.001 and 0.01 | Any | Warning (yellow) |
| Less than 0.01 | Less than 0.1% | Warning (yellow) with low expected impact |
| Less than 0.001 | 0.1% or more | Alert (red) that requires investigation |

To diagnose and resolve SRM, go to [Managing SRM](https://docs.statsig.com/experiments/monitoring/srm).

## Guardrail metric alerts

The _Diagnostics_ tab lists the metric alerts attached to this experiment under _Guardrail Metric Alerts_. It displays each metric's current status and when it last triggered. When an alert generates, a banner appears at the top of the experiment and a matching card appears on the _Results_ tab. Select **Resolve** to clear an alert and record why.

For more information, go to [Rollout alerts](https://docs.statsig.com/metrics/rollout-alerts), which covers how to create an alert as well as how Statsig evaluates your alerts.

## Crossover troubleshooting

A crossover unit is a unit that logged exposures to more than one group of the same experiment run. Statsig can't attribute that unit's behavior to a single variant. The _Crossover units detected_ check appears when crossover units exceed 0.1% of exposed units.

### How Statsig Cloud handles crossover units

Statsig Cloud keeps a crossover unit in both groups instead of discarding it. Statsig SDKs produce crossovers rarely, and the units that do cross over tend to cross in every group rather than in one. Including them dilutes the measured effect slightly instead of biasing it toward one group.

Below 1%, treat the check as a prompt to find the root cause, not as a reason to discard the readout. Above 1%, contact Statsig in Slack: a rate that high usually points to an implementation problem.

Warehouse Native drops crossover units from the analysis instead of keeping them, because it often reads exposures from another assignment service where crossover rates run higher. For that behavior and its thresholds, go to [Monitor an experiment](https://docs.statsig.com/statsig-warehouse-native/features/monitor-an-experiment) in the Warehouse Native documentation.

### Common causes of crossover units

| Cause | What to look for | What to do |
| --- | --- | --- |
| The client bootstrapped with values generated for a different unit | Exposures with the `BootstrapStableIDMismatch` reason in the exposure stream | Pass `getClientInitializeResponse` the same `stableID` the client uses at runtime. Go to [BootstrapStableIDMismatch](https://docs.statsig.com/sdks/debugging#bootstrapstableidmismatch). |
| A client SDK and a server SDK both evaluate the same experiment for the same user | One unit ID under two groups, with exposures logged from two SDK types | Evaluate an experiment for a given user in one place. If both SDKs must evaluate it, confirm that a configuration update reached both before you read results. |
| A client holds cached values from before a configuration change | Crossover that starts right after you change allocation, targeting, or the experiment's salt | Avoid changing a running experiment's configuration. To change group structure, [reset the experiment](https://docs.statsig.com/experiments/ending/reset) instead. |

### What doesn't count as crossover

Two patterns look like crossover in the exposure stream, but neither triggers the check:

| Pattern | Why it isn't crossover |
| --- | --- |
| Exposures with the `Unrecognized` reason | The definition was missing from the SDK's payload, so the exposure carries no group. A unit that returns the default value on one check and a real variant on the next has one analyzed exposure, not two conflicting ones. Go to [Evaluation reasons](https://docs.statsig.com/sdks/debugging#evaluation-reasons). |
| Exposures from an earlier run | The check compares exposures within the current analysis window. [Resetting an experiment](https://docs.statsig.com/experiments/ending/reset) generates a new salt and starts a new window, so a unit that was in control before the reset and in test after isn't flagged. Statsig doesn't exclude those units from the new run's analysis. |

### Prevent crossover with persistent assignment

Configure [persistent assignment](https://docs.statsig.com/server/concepts/persistent_assignment) on a supported server SDK before you start the experiment. Persistent assignment saves each unit's evaluation the first time the SDK evaluates it, then loads that saved evaluation on later calls. The unit keeps its group even when the experiment's configuration changes, which is the only way to keep an assignment stable through a configuration change.

If you can't pinpoint the cause, contact Statsig in Slack for help.

## Exposure streams

The _Exposure Stream_ section on the _Diagnostics_ tab lists the most recent exposures for the experiment. Use it to confirm that checks arrive, that targeting resolves the way you expect, and that your SDKs evaluate against current configuration. Select **Show non-production logs** to include checks from non-production environments.

### Read an exposure row

| Column | What it shows |
| --- | --- |
| _Eval Time_ | When the SDK last applied the configuration it used for this check. It isn't the moment the SDK evaluated the unit. |
| _Received_ | The exposure's own time, corrected for clock skew. Read this column as when the evaluation happened. |
| ID column | The unit Statsig evaluated. The heading is the experiment's ID type, such as `userID`, `stableID`, or a custom ID. |
| _Rule_ | The rule that matched, such as _Failed targeting_. For each value, go to [Diagnostics rule meanings](https://docs.statsig.com/experiments/implementation/getting-group#diagnostics-rule-meanings). |
| _Reason_ | The evaluation reason, such as `Network:Recognized`. For each value, go to [Evaluation reasons](https://docs.statsig.com/sdks/debugging#evaluation-reasons). |
| _LCUT_ | Last Config Updated Time: the most recent configuration change reflected in the SDK. Go to [Evaluation times](https://docs.statsig.com/sdks/debugging#evaluation-times). |
| _Stale_ | `Yes` when the evaluating process used an older version of the experiment than the console holds. The _Rule_ value also carries a `(Stale version)` suffix. |
| _User Properties_ | The user object your code sent with the check. |

_Eval Time_ moves only when an SDK picks up a configuration change, so the gap between it and _Received_ widens the longer a project goes without one. Don't read that gap as delivery latency: neither column reports how long Statsig took to ingest the exposure. To measure SDK upload latency, turn on [SDK debug logging](https://docs.statsig.com/sdks/debugging) instead.

### Query the stream

The _Query Exposures_ panel beside the table controls what the stream returns. Choose a time range, select **+** next to _Filters_ to filter on a column or user property, then select **Apply**.

The time range reaches back 7 days at most. Calendar days older than that aren't selectable, and presets wider than 7 days don't appear. This limit applies to row-level exposure queries in the console for every project, and no setting extends it. It bounds the query, not your data.

### What the exposure stream can't tell you

Each query returns at most 100 rows, newest first, however wide the time range. Treat the stream as a recent sample for debugging rather than an export. It also lists every evaluation that reached Statsig, including rows that [bot filtering](https://docs.statsig.com/experiments/monitoring/bots) later removes, so it isn't the analyzed population. A row missing here is weaker evidence than a unit missing from your results.

For exposure counts over a longer window, select **View in Metrics Explorer** in the _Exposure Stream_ header. That view aggregates exposures and the 7-day limit doesn't apply to it.

## Cumulative exposures

To track growth per variant:

1. Open the _Results_ tab.
2. Find the _Cumulative Exposures_ card below the hypothesis. It shows the total exposures and each group's share.
3. Click **See More** to expand the chart.

**Figure: Cumulative exposures by group**

Assignment pauses between July 12 and July 20, so the stack holds flat near 20,000 units before climbing again to 35,774 across three evenly split groups.

Stacked area chart. X axis: Date. Y axis: Cumulative exposures.

| Date | Control | Test A | Test B |
| --- | --- | --- | --- |
| 2026-07-08 | 0 | 0 | 0 |
| 2026-07-09 | 3317 | 3291 | 2995 |
| 2026-07-10 | 5276 | 5272 | 5140 |
| 2026-07-11 | 6321 | 6424 | 6132 |
| 2026-07-12 | 6696 | 6762 | 6508 |
| 2026-07-13 | 6711 | 6777 | 6526 |
| 2026-07-14 | 6727 | 6791 | 6542 |
| 2026-07-15 | 6741 | 6807 | 6559 |
| 2026-07-16 | 6755 | 6823 | 6577 |
| 2026-07-17 | 6771 | 6839 | 6593 |
| 2026-07-18 | 6784 | 6851 | 6606 |
| 2026-07-19 | 6795 | 6864 | 6618 |
| 2026-07-20 | 6813 | 6883 | 6636 |
| 2026-07-21 | 8731 | 8749 | 8671 |
| 2026-07-22 | 8880 | 8932 | 8853 |
| 2026-07-23 | 9052 | 9090 | 9019 |
| 2026-07-24 | 9214 | 9257 | 9212 |
| 2026-07-25 | 9343 | 9405 | 9344 |
| 2026-07-26 | 9490 | 9544 | 9477 |
| 2026-07-27 | 9651 | 9715 | 9688 |
| 2026-07-28 | 9798 | 9890 | 9868 |
| 2026-07-29 | 9951 | 10060 | 10042 |
| 2026-07-30 | 10104 | 10244 | 10220 |
| 2026-07-31 | 10278 | 10416 | 10376 |
| 2026-08-01 | 10425 | 10548 | 10503 |
| 2026-08-02 | 10564 | 10688 | 10632 |
| 2026-08-03 | 10734 | 10861 | 10841 |
| 2026-08-04 | 10908 | 11018 | 11019 |
| 2026-08-05 | 11060 | 11189 | 11184 |
| 2026-08-06 | 11216 | 11348 | 11344 |
| 2026-08-07 | 11383 | 11498 | 11496 |
| 2026-08-08 | 11527 | 11637 | 11635 |
| 2026-08-09 | 11645 | 11786 | 11779 |
| 2026-08-10 | 11839 | 11951 | 11984 |

The chart shows how many units entered each group over time, so you can identify ramp issues early. A band that flattens means the experiment stopped assigning units, and a band that outpaces the others points at an uneven split.

