Flag Evaluation Analytics
Every flag has an Analytics tab that shows what the flag actually served. Open it to confirm a rollout is reaching the share of traffic you set, to see whether a rule matches anyone at all, or to check that a flag you’re about to remove has stopped being read.
Analytics are on every plan, Free included, and every role can see them, Viewers too.
Opening the tab
Section titled “Opening the tab”Open a flag and choose Analytics. Pick an environment, then 7 days, 30 days or 90 days. Days run in UTC. The last point on the chart is labeled Today because that day is still in progress, so a dip there isn’t a drop in traffic. A range never starts before the day the flag was created.
What the tab shows
Section titled “What the tab shows”The top line gives the total evaluations in the range and when the flag was last evaluated. Below it:
- A daily chart, one line per variation.
- A variation table with each variation’s evaluations and share. A variation deleted since keeps its row, marked (deleted), so its traffic still adds up to the total.
- Where the traffic came from, a breakdown by the part of the targeting that served each evaluation. It has its own section below.
If the flag had no evaluations in the range, the tab says so instead.
What counts as an evaluation
Section titled “What counts as an evaluation”The numbers come from the evaluation events your SDKs send. They count evaluations, so one user evaluated ten times counts ten times. Every evaluation is in there, whatever served it: a targeting rule, a rollout, the default variation or the off variation.
How often a read gets reported depends on where your code runs:
- Server SDKs report every read. That covers Node.js, Cloudflare Workers, Python, Go, Java, C#, Ruby, PHP and
@featureflip/js. - Browser and mobile SDKs report each flag, variation and user about once an hour, and again when the page or app comes back to the foreground. For a client-side flag the count follows how many people read it far more closely than how many times. Read reporting has the details.
- A client created with
sendEvaluationEvents: falsereports no reads, so Featureflip counts every flag it sends that client instead.
A count of zero means no SDK reported an evaluation in that environment. That usually means no traffic, but an SDK that can’t reach Featureflip reports nothing either.
Where the traffic came from
Section titled “Where the traffic came from”This table splits the range’s evaluations by what served them. Your rules come first, in evaluation order and labeled the way the targeting editor labels them. Rules you’ve deleted since come next, then these:
| Source | What served the evaluation |
|---|---|
| Default variation | No rule matched |
| Flag off | The flag was off in this environment |
| Prerequisite not met | A prerequisite flag didn’t serve the variation this flag needs |
| Error | The SDK couldn’t evaluate the flag and served its fallback value |
| Flag not found | The SDK didn’t have this flag and served its fallback value |
| Unknown | An SDK version that doesn’t report a reason yet, or an evaluation recorded before sources were tracked |
Click any row to see the variations that source served.
Unknown shrinks as you upgrade. Server SDKs report the reason from JavaScript, Node.js and Cloudflare Workers 2.16.0, Python 2.10.0, C# 2.12.0, Go 2.11.0, Java 2.13.0, PHP 3.7.0 and Ruby 2.13.0. Browser and mobile reads get their source on the server, so those need no upgrade.
A rule keeps its history when you replace the whole targeting list, through Terraform, the API or the MCP server’s update_targeting. Any rule whose content didn’t change keeps its id, and its counts stay with it. Changing a rule’s rollout percentages gives it a new id, because it’s now a different split.
Checking a percentage rollout
Section titled “Checking a percentage rollout”Under each percentage-rollout rule sits a split check. Expand the row and each variation’s weight appears under Configured, beside the share it served under Actual.
The check is a sample-ratio test (Pearson’s chi-squared) on that rule’s evaluations, and it reads one of four ways:
- Split matches the configured weights.
- Split doesn’t match the configured weights (p < 0.001), shown as a warning. It appears only when the result is that unlikely by chance and at least one variation is 2 percentage points or more off its weight. The counts are evaluations, and on a busy flag a skew too small to matter would otherwise come out significant.
- Not enough traffic to check the split yet. Some variation is expected to have fewer than 5 evaluations.
- Served a variation this rule doesn’t split across. The rule served a variation outside its split, usually one deleted since, so there’s nothing to compare against.
If the rule or the flag’s variations changed during the range, a note says so. The numbers then mix two splits, and a shorter range shows only the current one.
A mismatch is worth understanding before you widen a rollout. With evaluation counts, the usual cause is code that reads the flag more often on one branch than the other. If the new checkout checks the flag in two components and the old one checks it once, the people are split correctly but the new variation’s evaluations are counted twice. Contexts without a user_id don’t skew the split, because they skip the rule and never reach it.
From the API
Section titled “From the API”The same breakdown, minus the daily chart, is on the Management API:
GET /api/v1/orgs/{org}/projects/{project}/flags/{flag}/environments/{env}/evaluations?days=30days is 7, 30 or 90, and defaults to 7. The response carries the window (fromUtc, toUtc), totalCount, lastEvaluatedAtUtc, a variations list with each one’s count and share, and a sources list in the order the tab shows. A rule source has its ruleId, and a percentage-rollout rule adds a rollout object with the configured weights, pValue and flagged. Any role can read it. See the API Reference for the full contract and Authentication for tokens.
From an AI agent
Section titled “From an AI agent”The MCP server has a read-only flag_evaluations tool that returns the same numbers. Before an agent ramps a rollout, have it ask something like “is the new-checkout rollout in production serving the split it’s set to?”
This tab or an analytics integration?
Section titled “This tab or an analytics integration?”The Analytics tab counts what Featureflip served. To see what people did afterwards, such as whether the new checkout converted better, send each evaluation to your product analytics tool with an evaluation inspector. Analytics Integration shows how for PostHog, Amplitude and others.
Next steps
Section titled “Next steps”- Rollout Strategies: how percentage rollouts assign users
- Stale Flag Detection: what evaluation data says about a flag nobody reads
- Analytics Integration: exposures in your own analytics tool
- MCP Server:
flag_evaluationsand the other tools