Routing settings
Routing settings change how one slot is routed, or the whole site. This guide gives each setting with its range and default, and shows when and how to change it.
setchanges what visitors get within about 2 minutes, with no deploy. Run it with--dry-runfirst, as for any act.
The settings
| Setting | For | With set |
In the config’s slots |
Range | Default |
|---|---|---|---|---|---|
| Fixed share | A slot | fixed_share |
fixed_share |
0 to 1 | 0 |
| Weights of the split | A slot | No | weights |
A number from 0 to 1,000,000 per variant key, one of them positive | Even |
| Personalization | A slot | personalization |
personalization |
On or off | On |
| Floor | A slot | floor |
floor |
0 to 1 | Routing’s own, auto |
| Cap | A slot | cap |
cap |
0 to 1 | Routing’s own, auto |
| The control’s share | The site | control_share |
No | 0 to 1 | 0.1 |
| The random slice | The site | random_control_share |
No | 0 to 1 | 0.05 |
| Visit length | The site | episode_window |
No | 1 second to 400 days | 7 days |
| Routing | The site | routing |
No | On or off | On |
With set, shares take 0.5 or 50%, the visit length takes 7d, 24h, 30m or seconds, and floor=auto or cap=auto removes a bound you set. A slot’s settings take its address, as npx routingcat set home/hero personalization=off; a page’s address sets each of its slots. The site’s settings take no address.
In routingcat.config.json, a slot’s settings go under its address in slots, such as home/hero. There, a share is a number from 0 to 1, such as 0.5, and personalization is on or off.
Run a classic A/B test, or test prices
A fixed share takes part of a slot’s routed visits out of routing and splits them evenly between its variants, or by the weights you declare. Each visitor in that part keeps the same variant on every visit, not only within one. Routing steers the rest.
Weights are relative to each other: weights of 1 and 2 give the second variant two thirds of the split. A variant the weights leave out weighs 0, as does one you weigh 0: none of the split’s visitors see it. One weight must be positive.
The split holds when its variants change. A variant you add draws its share, in proportion to its weight, from the other variants’ visitors, and the rest keep theirs. When you pause or remove a variant, only its own visitors move, to the variants left; a weight you change moves visitors into that variant or out of it alone.
At 1, the slot is a classic A/B test, and it is the right setting for prices: under a conversion objective, routing would drift toward the cheapest price, which usually converts best. With a fixed split, you weigh conversions against revenue yourself. The control still sees the default.
The slot’s scorecards then also get a measured comparison of its variants, over the split visits. Changing a slot’s settings marks its open scorecards, since the visits they compare change from then on:
$ routingcat set home/hero fixed_share=50% floor=autoset · done · op_01m4zbfqr0fa49v710xk3sc2w2 · registry version 20 home/hero fixed_share: 0 → 0.5 publications pb_01m4zbfqr0fwqttp9y5atppz0f scorecard ev_01kx68ntc0fgnbx7xqtn0wa7xx: support changed scorecard ev_01kx68ntc0fz2tfkmdtfzpescs: support changed scorecard ev_01ky9xn1r0ebbtkka94kcpe432: support changed scorecard ev_01m1rgqs60eg4ab70xdf6s4fb7: support changedA price on your site is also a trade-off. Each visitor’s browser picks their variants from routing data anyone can read, so a determined visitor could pick the lower price, while most visitors browse normally. Your agent explains this before it builds one, then does as you choose: see Weigh a variant your server honors.
Route everyone the same way
Personalization off stops a slot from learning for whom: every visitor is routed the same way, while routing still favors the likely best and keeps exploring. Turn it off when one answer for everyone is what you want, or when routing data grows too large, since a slot without personalization takes far less.
On your site, each visitor’s browser fetches the routing data of the page it shows, which takes at most 128,000 bytes a page: plan and push warn above 96,000, and past the limit every visitor gets the page’s defaults, unrouted, until a push brings it under.
Bound a variant’s share
A floor and a cap bound each variant of a slot: every variant’s chance of being picked for a new routed visit stays between the floor and the cap. They bound chances, not counts of visits, and apply to the routed visits outside the slot’s fixed share, which keeps its split as declared. They don’t apply to the control, or to visitors who already have their variant for the visit.
- They limit exposure, and guarantee no result. A variant held at its floor still costs conversions if it is worse.
- They must fit the slot’s live variants: the floor at most the cap, all the floors together at most 100%, all the caps together at least 100%.
setrefuses bounds that can’t hold, with the invalid setting message. Bounds in your config that can’t hold are refused byplan, and fail the push. setandplanwarn when bounds leave routing little room: floors that take most of the slot, or a cap at or below an even split.
Change the control or the random slice
- The control’s share sets who always sees the defaults, and so what the measured gain compares with. Below 0.05, the measured gain takes longer to settle, and at 0 there is none, which
setandstatuswarn of. So lowering it below 0.05 takes your agreement, given with--confirm, as innpx routingcat set control_share=0.02 --confirm. Without it,setrefuses and says what it costs. - The random slice is the share of routed visits split evenly whatever routing believes, so every variant keeps being tried.
A change to either applies to every routed page together.
Change the visit length
episode_window sets how long a visit lasts: the stretch during which a visitor keeps the same variants, and the longest an objective’s window can be. It applies to visits that start after the change. It can’t be shorter than the window an objective declares; set refuses that, so shorten the window in code first.
A longer visit allows a longer window, which slows learning by as much.
Turn routing off
npx routingcat set routing=off makes every page serve its defaults to every visitor: the quickest way to stop routing everywhere. Nothing learned is lost: turning it on again resumes from where routing stopped, and visitors still in a visit get back the variants they had.
While it’s off, a production push still registers its changes, and its receipt reads NOT LIVE; they reach visitors once routing is on again.
$ routingcat set routing=off --dry-runset · dry run: nothing written · registry version 19would change st_01kx0f96m0fm2r1cde30xrqn1a routing: on → off routing now at version 2command routingcat set routing=offYour plan can hold routing off too, on every site it covers: on Hobby, until the sites’ owner has a card on file, or once their sites are past Hobby’s visitors a second month running; on Pro, at the owner’s monthly cap. set routing=on is then refused until that cause ends, as Plans, billing and emails explains.
Keep code and live in agreement
A slot’s settings can live in your config, under its address in slots, and a production push applies a setting only when the config changed it since the previous production push. So a set holds until then. After set on a slot whose entry in slots declares that setting, write the same value there; deleting a declared setting from the config puts it back to its default at the next production push. A setting the config never declares stays as set left it.
The site’s settings exist only in RoutingCat, with nothing in code to change. npx routingcat show home/hero prints a slot’s settings, and its drift where code and live differ. The dashboard shows every setting, read only, in the site’s settings, under its Home: see Read a site’s settings.