Variants & control group
Whole-journey variants let you A/B/n test entire journeys against each other, and a control group holds back a share of your audience so you can measure how much the journey actually lifts conversions - not just how many people converted.
This is different from the Experiment node, which splits a downstream flow mid-journey. Variants split right at the entry: there's a single shared Trigger, and the journey fans out into a branch per variant straight off it.
When to use which
| You want to test | Use |
|---|---|
| Two structurally different journeys against each other (a 3-email series vs a single WhatsApp nudge) | Journey variants |
| One step inside an otherwise identical journey (subject line A vs B on the second email) | Experiment node |
| Whether the journey is worth running at all (incremental impact vs doing nothing) | Control group |
You can combine them: a journey with variants can still contain Experiment nodes deeper in a variant's flow.
How variants work
- There's one shared Trigger (the journey's normal entry). The split happens there - you don't add a Trigger per variant. After you save, the Trigger node shows one output per treatment variant - labeled with the variant's name and its traffic % - and you wire each output to the first node of that variant's flow. If a control group exists, the Trigger also shows a dashed Held out row with the control's share (it has no output).
- Each entrant is assigned to exactly one variant, deterministically: the assignment is a stable hash of the user and the journey, so the same user always lands in the same variant of the same journey. Entering twice never flips someone between arms mid-test.
- Percentages across all variants (including the control group) must add up to 100%. You don't normally set them by hand - the editor auto-splits the traffic for you as you add and remove variants (see below) - and it blocks saving until they sum to 100.
- Assignment happens once, at entry. Users already flowing through the journey are pinned to the variant they entered with - editing the split later only affects subsequent entrants.
If a variant isn't wired yet
Each treatment variant should have its trigger output connected to a flow. If a variant's output hasn't been wired to a dedicated branch, entrants assigned to it fall back to the journey's plain first branch instead of being dropped - so a half-configured test degrades safely. Still, wire every variant before activating: an unwired variant silently measures the same flow as the default branch, which tells you nothing.
Creating variants
- Build your journey with its single Trigger as usual.
- Open Variants from the journey toolbar. Every journey opens as a single Variant A at 100% - the whole journey is Variant A until you split it.
- Click Add variant to split. Each new treatment is auto-named Variant A, Variant B, and so on, and the percentages redistribute evenly for you - two variants become 50/50, three become 34/33/33, and so on. You can still override any value by typing into its % box; the running Total at the bottom must reach 100%.
- Optionally click Add control group to add a holdout (see below). It seeds at 20% and the treatments re-split the remaining 80%. A journey can have at most one control group - the button disappears once one exists.
- Save. Saving is disabled while the percentages don't sum to 100%. The trigger always shows at least Variant A - on the first save, the journey's existing flow is wired onto Variant A's output automatically, so you never have to reconnect the baseline.
- The Trigger node now shows one output per variant, each labeled with its % - drag from each output to the first node of that variant's flow on the canvas. The control group gets no output; it has no flow by design.
You can remove a variant from the same modal at any time - the remaining percentages rebalance back to 100% automatically. The last remaining treatment can't be removed; a journey always keeps at least one variant.
Duplicating a variant
Testing a tweak to an existing variant - same flow, one different message or wait - is far quicker to set up by copying the variant you already built than by re-wiring a new one from scratch.
In the Variants modal, each treatment row has a Clone (copy) icon. Clicking it:
- adds a new variant named after the source with "(copy)" appended, with the percentages redistributing just like Add variant, and
- on Save, duplicates that variant's entire downstream flow - every node reachable from its Trigger output, plus the wiring between them - and connects the copies to the new variant's Trigger output.
The copied nodes are offset on the canvas so they don't sit on top of the originals; drag them where you like and edit the one step you wanted to change. Because the copy only materializes on Save, hitting Cancel discards both the new variant and its node copies - nothing is left behind. Control groups have no flow, so they have no Clone action.
Setting the traffic split
The editor keeps the split at 100% for you (even on add/remove), but you can always type exact values. A few practical rules of thumb:
- Even splits reach a verdict fastest. For a two-variant test, 50/50 (or 45/45/10 with a control group) accumulates evidence for both arms at the same rate.
- Control groups are usually 5–20%. Large enough to measure against, small enough that you're not withholding the journey from a big slice of your audience. High-traffic journeys can afford smaller holdouts.
- Avoid tiny slices. A 5% treatment variant on a low-traffic journey may take months to say anything conclusive.
Because assignment is deterministic per user, changing the split moves the boundaries between arms: new entrants follow the new percentages, while anyone already enrolled keeps the variant they entered with.
Control group
A control group is a variant that is held out: users assigned to it are counted as entrants but receive nothing. They never enter the flow - no messages, no waits, no side effects. Comparing what the treated audience does against this "do nothing" baseline is the only way to know the journey's true incremental impact.
To add one, open Variants and click Add control group, then give it a share (for example 10%). It has no trigger output and no flow - it's a pure holdout, marked Held out in the variants list.
Under the hood, the control group is just a variant with the control flag, so it lives in the same Variants editor as everything else - one place for A/B/n and holdouts. When a user lands in the control group, Joryio still:
- counts them in the journey's total entries, and separately in its control entries, and
- records a control-arm marker event for that user, so their later purchases can be matched against the same conversion window as the treated audience.
That bookkeeping is what makes the holdout measurable rather than just skipped.
How the numbers appear
A journey with variants reports its entries in two counters:
- Total entries - everyone who entered the journey, including users held out in the control group.
- Control entries - the held-out subset, counted separately.
The treated audience is everyone in total entries who isn't in control entries. Keep this in mind when eyeballing send counts: a journey with a 10% control group will always show about 10% fewer sends than entries, by design.
Reading the uplift tile
When a journey has a control group, its analytics view shows an uplift vs control pill next to the revenue figure. It compares in-window revenue per recipient for the treated audience against the held-out control and reports the relative lift - or the incremental revenue when the control bought nothing. A negative number is shown honestly: it means the journey under-performed doing nothing for that window.
How to read it:
- Positive uplift - the journey is generating revenue that would not have happened on its own. This is the number to report, not raw attributed revenue.
- Roughly zero - the journey's "conversions" are mostly purchases that would have happened anyway. Consider changing the offer, timing, or audience.
- Negative uplift - the treated group did worse than the holdout. Rare, but real (over-messaging can suppress purchases). Investigate before scaling.
The uplift populates once there is real traffic: treated sends, control entrants, and purchases inside the conversion window. Until all three exist, the pill stays empty rather than showing a misleading early number. Revenue matching uses the same revenue attribution engine as the rest of analytics, so the treated and control arms are measured identically.
When to conclude
Resist the urge to call a winner after the first good afternoon. The same statistics that govern campaign A/B tests apply here - see Statistical Significance for how confidence intervals and significance testing work in Joryio.
Practical guidance:
- Run through at least one full business cycle (usually a week or more), so weekday/weekend behavior is represented in every arm.
- Decide the metric before you start - revenue per entrant, conversion rate, or a primary conversion event - and judge only on that.
- Don't peek-and-stop. Checking daily is fine; stopping the moment one arm noses ahead almost guarantees false winners. Wait until the difference is stable and the entrant counts are meaningful.
- Conclude by rebalancing. When you have a verdict, open Variants and route new entrants to the winner - set it to 100% and remove the losing variants (or keep a small control group running permanently to keep measuring incrementality).
Example: testing a new welcome journey
Suppose your welcome journey converts well, and you want to know whether adding a WhatsApp touchpoint beats the current all-email version - and how much the journey earns you at all.
- Open Variants and Clone your current flow's variant - you now have
Current (A)andCurrent (copy), each with the full email series wired up. Rename the copyEmail+WhatsApp (B)and, on the canvas, swap its email #2 for a WhatsApp message. - Back in Variants, add a control group and adjust the split to
Current (A)45%,Email+WhatsApp (B)45%, control 10%. Save. - Wire the Trigger's A output to the first email of the old series, and the B output to the first node of the new mix. The control needs no wiring.
- Activate and let it run for two full weeks.
- Read the results: the uplift pill tells you what the journey as a whole earns versus doing nothing; comparing A's and B's conversion and revenue numbers (with Statistical Significance in mind) tells you which variant to keep.
- Conclude: set the winner to 90%, keep the 10% control if you want a permanent incrementality readout - or fold it back in and set the winner to 100%.
FAQ
Can a user end up in two variants of the same journey? No. Assignment is deterministic per user per journey - one user, one variant, every time.
What happens if I remove the control group mid-test? The uplift measurement only computes while a control variant is configured, so the pill stops updating for new data. Entrants already held out stay held out for the run they entered. If you want a permanent incrementality readout, keep a small control group running indefinitely.
Do I need a control group to run variants? No - variants alone give you A/B/n. The control group is only required if you want to measure incremental impact rather than just compare variants to each other.
Can I change names and percentages while the journey is live? Yes, from the same Variants modal. Users already in flight keep their assigned variant; the new split applies to new entrants.
Personalized variants (ML)
If you want the system to learn which variant works best per user rather than fixing the split yourself, see Personalized Variants in the Experiment node - it trains a per-user model after a testing phase and routes each user to their predicted-best path, with a holdout to measure the ML lift.