Traffic share
What the Traffic share column means in the bandit arms table: a plan for future visits, or a record of past traffic?
TL;DR
Traffic share is an expected plan, not “what percent of visits this arm already got”.
The bandit estimates: how likely is the next /go visitor to land on this article or outbound? A number from 0 to 1 (shown as %). Active arms roughly sum to 100% (after share constraints: exact / min / max).
For historical volume, use the Journeys column — not Traffic share.
Share constraints (min / max / exact)
On an article or outbound you can set:
| Field | Meaning | Badge |
|---|---|---|
Exact (strict_share) | Exactly N% of traffic | =N% |
Min (min_share) | At least N% (if no exact) | ≥N% |
Max (max_share) | At most N% (if no exact) | ≤N% |
If exact is set, min and max for that arm are ignored. The entity fields are the source of truth; locking share from the dashboard writes strict_share.
On save, the sum of exact shares plus min floors (without exact) across active arms cannot exceed 100% — otherwise save is blocked.
Where it appears in the UI
| Place | What you see |
|---|---|
| “Articles & outbounds in rotation” table | Current computed share (bandit_arm_state.traffic_share) |
| Donut / distribution | Same current shares for active arms |
| Dynamics chart → traffic metric | History of those computed shares over time |
In all three cases this is the allocation plan (or its history), not measured past traffic.
Expected vs actual share
| Expected (“Traffic share”) | Actual | |
|---|---|---|
| Question | Where will the next visits go? | Where did visits already go? |
| Source | Monte-Carlo over Thompson / policy + lock/max | Count of journeys per arm |
| In UI | Traffic share column, Dynamics (traffic) | Journeys, funnel, period metrics |
| Updates | On share recompute (decision / settings / ComputeShares) | As tracking events arrive |
Example: an arm at 40% with few journeys means the bandit intends to send ~40% of new visits there. Over a short period, the realized share can differ a lot due to randomness and small sample size.
How it is calculated
1. Inputs
For each active arm, metrics come from analytics over analysis_window (often 7 days, product setting):
alpha/beta(from the reward mode: depth, revenue, conversion…);- journeys / mean_reward as needed;
- manual rules:
strict_share/locked_share,min_share,max_share, pin.
Cold start (few total journeys) → closer to uniform allocation.
If Min visits before allocation (min_allocation_journeys > 0) is set, each arm is first warmed up on lifetime journeys: until it hits the threshold it gets uniform fill, ignoring the score. A single warmed-up arm does not start the algorithm — traffic goes to the others. Once two or more are warm, Thompson (or the selected algorithm) runs among them while remaining arms still get fill (|warmup|/|free|). 0 turns the setting off.
2. Monte-Carlo (share estimate)
The policy (usually Thompson Sampling) repeatedly simulates which arm would win. An arm’s win rate ≈ its expected selection probability.
Then caps apply:
- strict / locked — exactly that percent;
- min_share — floor; deficit taken from other free arms;
- max_share — ceiling; surplus redistributed to others.
Results (0…1) are stored in bandit_arm_state.traffic_share and snapshotted to analytics_arm_snapshots for the chart.
3. On a real /go hit
Each visit is chosen fresh (Beta sample / categorical over shares), not by a fixed round-robin of the percentage table.
On average the stream converges to the displayed shares; a single click is random. With few visits, plan and reality diverge.
How to read the table
- High share + high effectiveness — the bandit is confident and sending a lot of traffic.
- High share + “Insufficient data” — the plan is still noisy; don’t overreact.
- Low share despite strong metrics — check
max_share, competitors’ locks, pins, archived peers. - Locked share — the column should stay near that %; the free pool is split by the algorithm.
Outbounds use the same column as articles.
Dynamics chart
The traffic metric is not “% of visits in that hour”. It is the history of traffic_share snapshots (about every few minutes while the worker runs).
You see how the bandit’s plan changed over time (after recomputes, archives, new arms).
FAQ
Why don’t shares sum to exactly 100%?
UI rounding, archived rows in the list, or a stale snapshot after arm set changes. Focus on active arms.
Why is share high but journeys low?
Future plan ≠ accumulated history. The arm was activated recently, or /go volume is low.
Does the table date range change traffic share?
Journeys / purchases / CR can follow the selected period. Traffic share comes from current bandit state (last recompute), not “journey share over the period”.
How do I see the actual share?
Compare journeys: arm_journeys / sum(journeys). That is realized visit share — a different metric, not shown in the Traffic share column.
Related docs
- Reward modes (depth / revenue / conversion) — they drive
alpha/beta, hence shares. - Outbounds — same shares, different arm kind.