TL;DR
This guide turns a reversible signup-flow change into one defensible A/B test in a React and TypeScript application. It covers hypothesis and sample-size checks, stable browser assignment, safe control fallback, activation-time exposure, outcome instrumentation, Managed Warehouse and bring-your-own-warehouse paths, health checks, interpretation, and cleanup. The 0 → 1 → 100 path proves that the experiment is worth running and that exposure joins to outcomes, launches one controlled experiment, and finishes with a documented ship, iterate, or stop decision plus removal of temporary experiment code. If traffic, consent, identity, or measurement cannot support a valid test, reject the experiment. This guide is optimized for AI coding agents, and it is recommended that you hand it off to your agent of choice for implementation.Guide map
Give this guide to your coding agent
Copy this page’s URL and the prompt below into a coding agent that can inspect your repository. ReplaceREPLACE_WITH_REPOSITORY with the repository path or name and REPLACE_WITH_GUIDE_URL with this page’s public URL. Start in a branch, worktree, or disposable clone, and use a non-production GrowthBook environment and synthetic or approved test events for the first pass.
Task
Add a valid A/B test to an existing React application without paying for an experimentation plan. The application assigns each eligible browser to one signup flow, keeps that assignment stable, records exposure when the flow is actually rendered, records signup outcomes with the same identifier, and produces enough evidence to make a ship, iterate, or stop decision. This is an implementation guide for a coding agent. It does not stop after installing an SDK or rendering 2 components. It covers the decisions and evidence that turn a random split into an experiment:- A falsifiable hypothesis and a predeclared decision rule.
- A defensible experimental unit.
- A traffic and sample-size feasibility check.
- Stable assignment and safe fallback behavior.
- Separate assignment, exposure, activation, and outcome concepts.
- Managed Warehouse and bring-your-own-warehouse data paths.
- SQL receipts that prove events can join before results are trusted.
- Sample ratio mismatch (SRM), multiple-exposure, and bias checks.
- Bayesian and fixed-horizon frequentist interpretation.
- Rollout, rollback, and removal of temporary experiment code.
Use this guide when
- You have 2 behaviors that can coexist behind one code-level feature flag.
- You can define one primary outcome that would change a product decision.
- You can assign a stable user, account, or anonymous browser identifier.
- The treatment is reversible and both variants are safe enough for production.
- You have enough eligible traffic to detect the smallest effect worth acting on.
- You want GrowthBook Cloud Starter with Managed Warehouse, or the free GrowthBook path connected to an existing warehouse.
Do not use this guide when
- There is no decision to make. If the new path is required for legal, security, or platform compatibility reasons, validate it and release it. Do not randomize it.
- The treatment is not safe. Fix correctness, accessibility, security, and data-loss risks before exposing real users.
- Traffic is too low. A test that needs 6 months to detect a useful effect will usually accumulate product changes, seasonality, and implementation drift faster than evidence.
- The variants change several unrelated things. If the treatment changes pricing, onboarding, and navigation together, the result cannot identify the mechanism.
- Users influence each other across variants. A marketplace, collaboration product, classroom, or team workflow may require account-, group-, or cluster-level assignment instead of user assignment.
- You cannot observe the outcome. A rendered treatment without a trustworthy conversion or quality event is a rollout, not an analyzable experiment.
- The outcome is too delayed for the operating window. If the meaningful outcome arrives 6 months later, use an earlier validated proxy or another research design.
- Consent or policy forbids the required tracking. Do not generate a persistent anonymous identifier or send events until the application has the required consent or legal basis.
Tested stack
The code in this guide targets a client-rendered React application created with Vite and TypeScript. It was verified against the GrowthBook JavaScript and React SDK source at commite44a15af063860c7118f52508746356d55e5a91d, where both packages are version 1.7.0.
The same design works in other JavaScript frameworks, but the location of initialization and the moment of exposure will differ. For Next.js, Remix, or another server-rendered framework, do not copy the browser-only bootstrap blindly. Use the framework-specific SDK guidance and preserve the identity, event, and decision contracts in this guide.
Required access
You need:- Read and write access to the application repository.
- Permission to install npm packages and run the build and test suite.
- A GrowthBook organization with permission to create a data source, SDK connection, feature, metric, and experiment.
- Access to GrowthBook SQL Explorer for the Managed Warehouse path, or read access to the existing analytics warehouse for the BYOW path.
- The application’s analytics-consent policy and current identifier conventions.
- A product owner who can approve the hypothesis, minimum detectable effect, and final decision.
VITE_* variable.
Files the agent will create or change
The reference implementation creates or changes these files:End state
You are done only when all of the following are true:signup-flowreturns onlycontrolorstreamlined, and its code fallback iscontrol.- A stable
device_idis available before the flag is evaluated. - Repeated evaluations for the same
device_idreturn the same variation. - The feature is evaluated on the signup route, not globally on application boot.
- Rendering the feature under an experiment rule records one deduplicated
Experiment Viewedexposure with tracking keysignup-flow-v1. Signup Completedrecords the samedevice_idused for assignment.- SQL receipts show exposures and outcomes in the intended data source and prove they join by identifier.
- The observed traffic split has no unresolved SRM warning.
- Multiple exposures and variation-ID checks are clean.
- The primary metric, target effect, minimum runtime, sample target, and stopping rule were written before launch.
- The result is interpreted at the predeclared horizon, not the first moment a dashboard turns green.
- The final decision is recorded, the experiment rule is stopped, and the losing path has an owner and removal date.
Rollback
Rollback has 3 layers. Keep them independent so an incident does not require a code deployment.- Behavior rollback: In GrowthBook, replace or disable the experiment rule and serve
controlto everyone. Verify the application returns the control experience for a known test identifier. - Analysis rollback: Mark the experiment phase invalid if assignment or tracking was broken. Do not delete evidence. Fix the cause and start a new phase or experiment with a new seed and documented start time.
- Code rollback: Revert the application commit only if the shared feature wrapper or event code is itself unsafe. A config-fetch failure already falls back to
control, so ordinary treatment rollback should not require this step.
Understand the system before changing code
A useful A/B test is a chain of contracts, not a random-number function:Separate assignment, exposure, activation, and outcome
These terms are easy to collapse. Keep them distinct:- Assignment is the deterministic mapping from an identifier to a variation.
- Exposure means the unit actually encountered the treatment boundary. In this guide, evaluating
signup-flowinside the signup component triggers the SDK experiment event. - Activation is an optional, pre-treatment condition used to restrict analysis when assignment must happen earlier than meaningful exposure. It must not be influenced by the treatment.
- Outcome is behavior after exposure, such as completing signup.
main.tsx. Initialization only downloads definitions. The experiment event occurs when code evaluates a feature whose first matching rule is an experiment.
Do not use Signup Started as an activation metric for this experiment if the streamlined flow can change whether a visitor starts. Filtering on a post-treatment event can select different populations in each variation and bias the estimate. Evaluate the feature at the moment the signup UI is rendered instead.
Step 0: Decide whether the repository contains a valid experiment
Do this before opening GrowthBook.Inspect the repository
From the application root, collect evidence about the existing stack and instrumentation:rg is unavailable, use the repository’s normal search tool. Do not assume that id, anonymousId, and userId mean the same thing. Trace each identifier from creation through event ingestion.
Write down:
Write the hypothesis as a decision contract
Use one sentence:- Population: first-time visitors who render signup.
- Treatment: 3 steps versus 1 page.
- Primary metric: signup completion within 24 hours.
- Baseline: 10.0%.
- Minimum worthwhile effect: 1.5 absolute percentage points, or 15% relative.
- Harm boundary: no more than 0.5 absolute points of primary-metric harm, plus an operational error guardrail.
- Decision time: a fixed sample horizon and minimum runtime.
Choose the experimental unit
The experimental unit is the entity independently assigned to a treatment. The assignment attribute in GrowthBook must represent that entity. Use this test:Could 2 candidate units receive different variants without contaminating each other’s experience or outcome?For the reference signup flow, the visitor is anonymous before conversion. A first-party
device_id is a reasonable unit if one person using 2 devices can legitimately count as 2 independently treated browsers. It is not perfect person-level identity. State that limitation in the decision record.
Choose a different unit when the treatment operates elsewhere:
Never assign on a value that changes during the outcome window. Assigning anonymous visitors on
device_id, then analyzing only user_id after signup, silently drops non-converters and biases the result. This guide keeps device_id on both pre- and post-signup events. The authenticated user_id is additive.
Check traffic feasibility before building
Estimate the sample needed to detect the minimum worthwhile effect. The following approximation uses a 2-sided alpha of0.05, 80% power, equal groups, and a binary outcome. It is a planning estimate, not a replacement for a reviewed analysis plan.
Create scripts/estimate-signup-sample.mjs temporarily or run the body in a Node REPL:
Choose the data path
GrowthBook analyzes experiment assignments and metrics in a data warehouse. Pick one path before writing event code:
See Choose Your Data Path for the current architecture and plan comparison. Each experiment uses one data source. Do not send exposure to Managed Warehouse and outcomes only to a separate warehouse, then expect one analysis to join them.
The canonical implementation below uses Managed Warehouse. The BYOW replacement appears later.
Step 1: Provision the Managed Warehouse and SDK connection
Create the data source
In GrowthBook Cloud:- Open Metrics and Data → Data Sources.
- Choose Managed Warehouse and click Create.
- Record the selected data region:
us-east-1oreu-west-1. - Open the generated data source and confirm these tables exist:
events,experiment_views, andfeature_usage. - Open SQL Explorer and confirm a read-only query runs.
user_id and device_id identifiers, and starter metrics. The complete data shape is documented in Managed Warehouse.
Create the SDK connection
- Open SDK Connections.
- Click Add SDK Connection.
- Select JavaScript or React and the production environment.
- Copy the public client key, which begins with
sdk-. - Under the connection’s Attributes, ensure
device_idexists as a string and is marked as an Identifier. - Add
user_idas a string identifier if the application adds it after signup. - Add
app_environmentandapp_versionas non-identifier string attributes only if you will use them for diagnostics.
Install the SDK packages
Pin the versions while implementing so a later release does not change the test fixture during review:Add public environment configuration
Create.env.example:
eu-west-1, use:
.env.example; do not commit .env.local.
Create src/vite-env.d.ts so misspelled environment variables fail during type checking:
Step 2: Implement a stable anonymous identifier
The identifier must exist beforesignup-flow is evaluated and must survive reloads through the conversion window. This implementation uses a host-only, first-party cookie. It does not put email, name, IP address, or another direct personal identifier in GrowthBook.
Create src/experimentation/device-id.ts:
getOrCreateDeviceId() only after the consent manager reports an allowed state. Before consent, render control without running or tracking the experiment. Do not substitute a new in-memory identifier on every page load; that re-randomizes returning visitors.
If the app already maintains a durable anonymous ID, delete this file and pass the existing value as device_id. If experiments cross subdomains, a host-only cookie is not enough. Use the same parent-domain cookie policy as the existing identity system and test redirects explicitly. A new ID on the destination subdomain can cause re-bucketing and SRM.
Step 3: Initialize GrowthBook with controlled event schemas
Createsrc/experimentation/growthbook.ts:
device_idexists before feature evaluation.- The public client key loads the SDK payload.
- The event plug-in automatically emits
Experiment ViewedandFeature Evaluatedand powersgrowthbook.logEvent(). - The event filter rejects accidental custom event names. It does not make unsafe properties safe, so the event functions below use a closed schema.
- The URL drops query parameters, which may contain email addresses, invitation tokens, or campaign data that should not be copied without review.
init()waits at most 1.5 seconds. It returns an object rather than throwing for ordinary fetch failures.- A missing payload causes
useFeatureValue("signup-flow", "control")to return the explicit control fallback. - Streaming is off for the first implementation. Add it only when the application needs it and after testing lifecycle behavior.
user_id attribute to the top-level warehouse user_id column. It maps device_id, anonymous_id, or id to the top-level device_id column, preferring an explicit device_id. Use one key for one ID space. Never put a logged-in user ID in id and later introduce a browser ID in device_id; that mixes identifier semantics.
The plug-in batches events, uses fetch with credentials: "omit", keeps eligible browser requests alive across navigation, and uses sendBeacon during unload when available. Browser analytics delivery is best effort: never make a successful signup or its navigation wait for it. Keep server-confirmed business outcomes in the application database or existing analytics source of truth, and reconcile browser completion loss before trusting experiment results.
Step 4: Define narrow outcome events
Createsrc/analytics/signup-events.ts:
flow property is diagnostic. Do not calculate experiment lift by filtering this property. The authoritative variation comes from the experiment exposure table. If application code and exposure data disagree, investigate rather than making the outcome property the source of truth.
Step 5: Evaluate the feature at the treatment boundary
Createsrc/analytics/best-effort.ts. This boundary catches synchronous and asynchronous analytics failures without waiting for delivery. An analytics outage must not turn a completed signup into an error or a permanently submitting form.
src/analytics/best-effort.ts
src/features/signup/SignupExperiment.tsx:
Signup Started records once per mounted component after first form focus. It is useful for diagnosing funnel behavior, but it is not the denominator of the canonical proportion metric. The experiment exposure is the denominator because the hypothesis is about visitors who render the signup treatment.
The API creates the account before the browser records completion. This is appropriate for a UI experiment receipt, but the application database remains the durable source of account creation. For stronger delivery guarantees, emit the completion event from the server-side account transaction into the same warehouse with the same device_id, passed through a validated request field or first-party session. Do not block account creation on a third-party analytics response.
Mount the feature only on the eligible route
Create or updatesrc/App.tsx:
useFeatureValue() must only mount for the eligible population.
Initialize before the first render
Create or updatesrc/main.tsx:
Signup Completed twice. The production API should also use its own idempotency control for account creation.
Build before configuring production traffic
Run the repository’s checks:package.json and run the equivalent type-check, unit-test, and production-build commands. Do not publish an experiment rule to compensate for code that does not build.
Step 6: Create the feature and experiment rule
Create a string feature
In GrowthBook:- Open Features and click Add Feature.
- Set the key to
signup-flow. Feature keys cannot be renamed after creation. - Choose String as the type.
- Set the default value to
controlin every environment. - Leave production enabled with no rule until the code containing the fallback and both paths is deployed.
true and false into ambiguous semantics.
Deploy the dormant code first. Verify that production still serves control with no experiment rule. This separates deployment risk from treatment risk.
Add the experiment rule
After the dormant deployment is verified:- Open
signup-flowand create a draft revision. - Click Add Rule → Experiment.
- Set the tracking key to
signup-flow-v1. - Set Assign variations based on attribute to
device_id. - Map variation
0tocontroland variation1tostreamlined. - Set overall exposure to
100%and relative weights to50% / 50%for the canonical test. - Limit the rule to the production environment and any explicit eligibility targeting.
- Review, publish, and record the exact UTC publication time.
Confirm the feature payload before trusting events
Open the SDK connection endpoint shown in GrowthBook or inspect the request tocdn.growthbook.io in browser DevTools. Confirm the signup-flow definition contains an experiment rule and the expected values.
Then open /signup with a clean browser profile and check:
Step 7: Prove the Managed Warehouse data path with SQL
Wait for test events to arrive, then use SQL Explorer. Replace the tracking key only if you deliberately changed it.Confirm exposure counts and units
Confirm custom events and identifier coverage
missing_device_id must be 0. A completion with no assignment identifier cannot contribute to this device-level experiment.
Confirm exposures join to outcomes
This query takes each device’s first recorded exposure and checks for a completion in the following 24 hours:Check for multiple exposures
Inspect event properties without exposing raw form data
signup-events.ts should appear. If an email, password, full URL query, free-form error, access token, or request body appears anywhere in the event, stop the experiment, remove the field, and follow the organization’s incident and deletion policy.
Step 8: Define the fact metric and analysis
The Managed Warehouse creates an Events fact table. Build the primary metric on it rather than writing a one-off metric query.Create the primary proportion metric
- Open Metrics and Data → Fact Tables → Events.
- Click Add Metric.
- Choose Proportion.
- Name it
Signup completed. - Set the goal to Increase.
- Add a row filter:
event_name = Signup Completed. - Set a 24-hour conversion window if signup is expected to complete within one day.
- Set a minimum data threshold that prevents interpretation of tiny counts.
- Save the metric and use its preview to verify recent completions.
Signup Completed events from one device still count that device once. See Metrics and Fact Tables and Metric Examples for current metric semantics.
If the business outcome is revenue, sessions, or another non-binary quantity, do not coerce it into a proportion metric to stay on the free path. Use the metric type that represents the decision and check its current plan availability. A free but invalid metric is not useful.
Create the experiment record
The feature rule may create or link an experiment automatically. If it does not:- Open Experiments and click Add → Create New Experiment.
- Set the name to
Streamlined signup flow. - Paste the predeclared hypothesis.
- Set the assignment attribute to
device_id. - Set the experiment key to
signup-flow-v1. - Select the Managed Warehouse data source and its experiment assignment query.
- Add
Signup completedas the single goal metric. - Confirm the baseline variation is
controland the comparison isstreamlined. - Set the analysis start time to the recorded rule publication time.
experimentId must match exactly. Variation IDs must match the values represented by the experiment record. A variation-ID mismatch is a data-quality failure, not a naming inconvenience.
Do not add every available metric as a goal. One primary goal limits metric shopping and makes the decision legible. Track client error rate, API error rate, latency, and abuse signals as operational guardrails in the application’s monitoring system on Starter. If the current plan supports dedicated guardrail metrics, add only the predeclared ones and keep the external operational alerts.
BYOW branch: Keep the existing event pipeline
Use this branch instead of the Managed Warehouse tracking plug-in when the application already sends trustworthy product events to a supported warehouse. Do not run both implementations for one experiment unless you intentionally maintain 2 independent analysis systems. The GrowthBook SDK still performs assignment. Your existing analytics client records exposure and outcomes. GrowthBook queries the warehouse read-only.Define one warehouse event contract
Adapt this interface to the repository’s analytics client:event_id in the existing pipeline and deduplicate retries there. Do not use (device_id, event_name) as a unique key; the same device can validly start signup more than once.
Replace the Managed Warehouse plug-in with a tracking callback
The BYOW version ofsrc/experimentation/growthbook.ts should use the existing analytics client:
1.7.0 passes a third user argument to trackingCallback. Read identifiers from user.attributes, because those are the attributes used at evaluation time. Reading a mutable global user object can record an identity different from the one the SDK hashed.
Replace growthbook.logEvent() in signup-events.ts with analytics.track() using the same context() helper. Better yet, route both exposure and custom events through the application’s existing typed analytics module so they share retries, consent, timestamps, and identifier rules.
Configure the assignment query
On Metrics and Data → Data Sources, add or edit a device-level experiment assignment query. Adapt column and JSON syntax to the warehouse:timestamp, experiment_id, and variation_id. Return repeated legitimate exposure rows; GrowthBook uses them to detect units exposed to more than one variation.
Define a fact table over outcomes:
Signup completed proportion metric filtered to event_name = 'Signup Completed'.
If exposure uses device_id but the only durable completion has user_id, add an identifier join table that maps both IDs from login or account creation. The better canonical design keeps device_id on the completion event as shown. Never join all anonymous devices to a user retroactively without reviewing how shared devices, account switching, and historical identity affect the experiment unit.
Run warehouse receipts before launching
Use the warehouse’s SQL dialect to prove:Step 9: Add tests that protect assignment and event semantics
Tests should prove properties, not hard-code a bucket produced by an undocumented hash calculation.Test that analytics cannot block signup navigation
Createtests/best-effort.test.ts:
tests/best-effort.test.ts
npx vitest run tests/best-effort.test.ts. Also exercise the real signup flow in a browser with the ingestor request deliberately stalled, rejected, and blocked. Successful account creation must still navigate without an analytics wait; genuine account-creation failures must still display the form error. Check durable signup counts against browser completions and investigate differential event loss between variations.
Test deterministic assignment and exposure deduplication
Createtests/growthbook-assignment.test.ts:
Test the closed event schema
Createtests/signup-events.test.ts:
Add browser and API tests
The unit tests do not cover cookie persistence, real SDK payloads, navigation, or ingestion. Add the following cases to the repository’s browser suite:Step 10: Respect free, Pro, and Enterprise boundaries
Plan packaging changes. Verify current GrowthBook pricing immediately before publishing this guide or promising a capability. As verified on 2026-08-12, the relevant boundaries are:
The canonical test needs only a string feature, feature-flag experiment, proportion metric, Bayesian or fixed-horizon frequentist analysis, and SRM detection. Those are on the Starter path.
Do not tell a Starter user to “enable sequential testing,” “turn on CUPED,” or “use a Safe Rollout.” On Starter, use a fixed horizon for frequentist analysis, plan the sample with a documented external calculation, and monitor operational harm in the application’s existing alerting system. Upgrade features can reduce variance, formalize decisions, or automate release monitoring, but they do not make a weak hypothesis or broken identifier valid.
Budget Managed Warehouse events
Unlimited experiment traffic does not mean unlimited Managed Warehouse ingestion. The current GrowthBook Get Started page states a Starter allowance of up to 1 million events per month and a Pro allowance of 2 million before paid overage. The exact allowance and price are volatile; confirm the organization’s usage screen and pricing page before launch. The Managed Warehouse limit behavior is especially important on a free plan: when the limit is reached, event tracking stops for the remainder of the month and resets the next month. An experiment that keeps assigning users after outcome ingestion stops produces unusable results. Estimate monthly volume before launch:Step 11: Launch with a preflight record
Commit a short analysis plan beside the product specification or experiment record before publishing the rule:.invalid addresses are placeholders.
Run the prelaunch checklist
Before production assignment begins, verify:- Both variants pass accessibility, visual, API, and abuse-prevention tests.
controlis behaviorally equivalent to the pre-experiment path.- The deployed application returns control when the SDK endpoint is blocked.
device_idis generated or retrieved before feature evaluation.- Consent behavior matches policy in every supported region.
- The SDK connection targets the correct environment.
- The event ingestor host matches the Managed Warehouse region.
- A known test exposure and completion join in SQL.
- The experiment key and variation IDs match across feature rule, event table, assignment query, and experiment record.
- Internal employees, synthetic monitoring, automated tests, and known bots are excluded consistently if they are outside the target population.
- Operational alerts identify variation where possible without using the untrusted outcome property as assignment truth.
- The rollback owner can serve
controlwithout deploying code.
Ramp exposure without changing weights
If the new UI passed preproduction tests but you still want a small operational canary:- Publish with 5% overall exposure and a 50/50 relative split.
- Verify API error, client error, and latency signals for at least one full operating period.
- Check exposures, identifier coverage, and multiple-exposure SQL.
- Increase overall exposure to 100% while keeping the 50/50 weights.
- Record each exposure change and time.
Step 12: Treat health failures as blockers
GrowthBook runs experiment health checks. Open the experiment’s Health tab before reading metric lift. See Experiment Results for the current checks.Sample ratio mismatch
SRM means the observed allocation is implausibly different from the configured allocation. GrowthBook uses a chi-squared check and, by default, raises the warning at a very strict p-value threshold. It is evidence of an assignment, delivery, eligibility, or data problem, not evidence that one variant is popular. Investigate:- Conditional rendering that evaluates one variation more often.
- JavaScript errors that prevent one variant from completing exposure tracking.
- An unstable or missing assignment ID.
- Cookie behavior across domains or consent states.
- A changed relative allocation.
- Bot, internal, or geography filters applied after assignment.
- Ingestor blocking that differs by browser or route.
- An assignment query that drops one variation value.
Multiple exposures
A device appearing in both variations usually means it changed assignment identity, the experiment weights or seed changed, or the assignment query is wrong. Compare the first and last event attributes for affected devices. If assignment switched, the causal contrast is contaminated. Fix and restart rather than selecting whichever variation appeared first without a predeclared rule.Pre-exposure imbalance
If a metric differs substantially before exposure, first rule out SRM and multiple exposure. Then inspect timestamp latency, daily aggregates timestamped at the start of a day, outliers, and mismatched randomization and analysis units. A user-level outcome analyzed against session-level assignment can create misleading precision and imbalance.Failure matrix
The experiment troubleshooting guide provides additional causes. Preserve screenshots, queries, timestamps, and config revisions with the incident record.
Step 13: Use activation only when assignment must happen early
The canonical implementation evaluates the flag inside the signup page, so exposure is already close to treatment. It does not need activation filtering. Use an activation metric only when the application must assign earlier. For example, it downloads both modal implementations at page load but only some visitors become eligible to see the modal. The activation event must occur before the treatment can affect it or be independent of assignment. Valid candidate:- Define a binomial activation metric on the independent event.
- Add it under Experiment → Overview → Analysis Settings → Activation Metric.
- Verify the activation event carries the assignment identifier.
- Compare activation rates across variations. A material difference is evidence the activation condition may not be independent.
- Document both intent-to-treat results and the activated analysis when decision risk warrants it.
Step 14: Interpret results without shopping for a win
Do not begin with the effect estimate. Use this order:- Confirm data freshness through the full conversion window.
- Confirm the experiment reached the predeclared minimum runtime and fixed sample target, or the maximum runtime rule applies.
- Confirm SRM, multiple exposure, variation mapping, and identifier checks are clean.
- Confirm operational guardrails did not cross the rollback boundary.
- Read the primary metric’s point estimate and uncertainty interval.
- Compare the interval with the minimum worthwhile effect and harm boundary.
- Review secondary diagnostics as explanations, not alternate primary outcomes.
- Record one decision and its reasoning.
Bayesian interpretation on Starter
GrowthBook’s Bayesian engine reports a Chance to Win and a distribution for percent change. The default UI highlights a variation above the configured winning threshold and a clear loser below the corresponding lower threshold. Read the result as a distribution of plausible effects under the model and priors. Do not translate “95% Chance to Win” into “there is a 95% chance the implementation is correct.” Health, instrumentation, model assumptions, and practical effect size remain separate questions. A high Chance to Win with most plausible effects below the 15% relative minimum may be statistically persuasive but not commercially worthwhile. Conversely, an inconclusive Chance to Win with a wide interval may mean the test lacks precision, not that the variants are equal. Although Bayesian monitoring does not use the same fixed-horizon p-value rule, predeclare the minimum runtime, sample target, harm rule, and decision cadence. Repeatedly changing the decision after each dashboard refresh still creates an unstable operating process.Frequentist interpretation on Starter
GrowthBook’s frequentist engine reports a p-value and confidence interval. On the free path, sequential testing is not included, so use the fixed horizon written before launch.- Do not stop the first time
p < 0.05. - Do not extend only because
p = 0.06. - Do not change the primary metric after viewing results.
- Do not call
p = 0.20proof that the variants are identical. - Do not call a tiny but precisely estimated effect a win if it fails the business threshold.
0 supports a nonzero positive effect at the configured alpha. An interval also above the 15% relative minimum supports the stronger claim that the treatment likely clears the predeclared business threshold. An interval spanning material harm and material benefit is inconclusive. An interval narrow enough to exclude the worthwhile effect can justify stopping even when the point estimate is positive.
If the sample target lands before 14 days, continue to the predeclared minimum runtime to include weekly traffic patterns. After stopping assignment, wait until the last exposed unit’s 24-hour conversion window closes before the final analysis.
Treat segment findings as hypotheses
Browser, country, acquisition source, and device breakdowns can reveal bugs or plausible effect differences. They also create many opportunities for chance findings. Use slices to diagnose implementation first. If a surprising subgroup changes the shipping decision and was not predeclared, run a dedicated follow-up experiment or require stronger independent evidence. Do not target the treatment only to the “winning” slice discovered after the fact and describe it as confirmed personalization.Record the decision
Use a durable record:Step 15: Move from one experiment to a maintained system
The end state is not a dashboard with a winner. It is one production behavior, one readable code path, and a reusable experiment contract.Ship the selected behavior
For aship_streamlined decision:
- Stop the experiment analysis and record the final result.
- Replace the experiment rule with a forced
streamlinedvalue for production, or use the product’s approved temporary-rollout workflow. - Confirm the assignment callback no longer records new experiment exposures.
- Monitor the full population through at least one normal operating cycle.
- Open a cleanup change that makes streamlined behavior unconditional.
- Remove the control component, temporary variant types, diagnostic
flowproperties, and experiment-only tests. - Deploy the cleanup with the flag still forcing
streamlined. - Verify the unconditional implementation.
- Remove the feature check, archive the feature, and retain the experiment decision record.
retain_control:
- Force
controlimmediately. - Stop analysis after the last conversion window closes.
- Remove the streamlined code and experiment-only events.
- Remove the feature check if there is no active rollout need.
- Record what was learned and whether a materially different follow-up is justified.
iterate:
- Return everyone to
controlunless the treatment is required for another reason. - Do not mutate the old treatment under the same running phase.
- Create a new treatment with a new hypothesis and tracking key, such as
signup-flow-v2. - Recalculate feasibility from the new minimum worthwhile effect.
- Repeat the preflight and data receipts.
Add an experiment pull-request checklist
After the first implementation, require experiment changes to state:Monitor drift
Add alerts or scheduled checks for:- A material drop in exposure or completion freshness.
- Missing
device_idon any canonical signup event. - A new variation value outside
controlandstreamlined. - Units exposed to multiple variations.
- Managed Warehouse usage approaching the plan allowance.
signup-flowstill referenced after its cleanup deadline.
DIY versus GrowthBook
A coding agent can create a visual split in a few lines:- Identifier generation, consent, persistence, and cross-device semantics.
- A deterministic hashing algorithm and compatibility policy.
- Remote configuration, environment separation, authentication, and audit history.
- Caching, invalidation, fallback, and incident behavior.
- Exposure deduplication and unload-safe delivery.
- Assignment, outcome, and identity-join schemas.
- SRM and multiple-exposure detection.
- Metric windows, denominators, outlier rules, and statistical methods.
- Reproducible results and decision records.
- Flag ownership, stale detection, and code cleanup.
- The split is a short-lived internal engineering test rather than evidence for a product decision.
- Assignment already lives in a trusted system of record.
- The organization has a reviewed experimentation library and analysis pipeline.
- The team accepts ownership of health checks, statistics, privacy, and lifecycle.
- GrowthBook would duplicate a mature internal platform rather than replace one-off code.
Definition of done
Use this final, falsifiable checklist. “The feature renders” is not enough.Design
- The hypothesis names population, treatment, primary metric, minimum worthwhile effect, and harm boundary.
- The assignment unit matches the entity that independently receives treatment.
- Baseline rate and eligible traffic come from current data.
- Sample target, minimum runtime, maximum runtime, and stopping rule are recorded before launch.
- Both variants are reversible and safe enough for production.
Implementation
-
device_idor the chosen identifier exists before evaluation and remains stable through the outcome window. - The code fallback is the known-good control.
- The feature is evaluated only at the real treatment boundary.
- Feature payload timeout renders control without blocking signup indefinitely.
- Exposure and outcome use the same identifier type.
- Event functions accept only reviewed, typed properties.
- Email, password, tokens, raw form values, and unreviewed URL queries are absent from events.
- Type-check, unit tests, browser tests, and production build pass.
Data
- The regional ingestor or BYOW destination receives an exposure and a known completion.
- SQL receipts show zero missing assignment IDs for canonical events.
- Exposures join to outcomes in the configured conversion window.
- Experiment key and variation IDs match every layer.
- Multiple-exposure query returns zero unresolved rows.
- Projected event volume fits the current plan with operating headroom.
Analysis
- GrowthBook uses the correct data source, assignment query, identifier, and proportion metric.
- SRM, multiple-exposure, and relevant pre-exposure checks pass.
- The last assigned unit has completed the metric window before final analysis.
- Bayesian or frequentist results are interpreted according to the predeclared rule.
- Segment exploration is labeled exploratory unless predeclared.
- Operational guardrails remain within their thresholds.
Decision and cleanup
- A ship, retain, or iterate decision includes dates, sample, effect interval, health status, and owner.
- The experiment rule no longer assigns new units after the decision.
- Production serves the selected behavior without depending on a completed experiment.
- The losing code has been removed or has a dated cleanup change.
- The temporary feature is archived after code removal.
- The experiment record and SQL receipts remain available for future review.
Source map and freshness
This guide was verified against GrowthBook public source commite44a15af063860c7118f52508746356d55e5a91d on 2026-08-12.
Product and SDK dependencies
Volatile details to reverify
Before the next publication or substantial edit, recheck:- Latest
@growthbook/growthbookand@growthbook/growthbook-reactversions and peer requirements. init()return fields and plug-in option names.- Regional ingestion hosts and event payload mapping.
- Managed Warehouse allowance, stop/overage behavior, and SQL column names.
- Starter, Pro, and Enterprise availability for metric types, sequential testing, CUPED, power tools, guardrails, and release controls.
- GrowthBook UI labels for SDK connections, features, fact tables, metrics, and experiments.
- React, Vite, TypeScript, Vitest, and Node versions in the tested fixture.

