[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-posthog-configuring-experiment-rollout":3,"mdc--shis4r-key":38,"related-org-posthog-configuring-experiment-rollout":1365,"related-repo-posthog-configuring-experiment-rollout":1540},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":33,"sourceUrl":36,"mdContent":37},"configuring-experiment-rollout","configure PostHog experiment rollouts","Configures the rollout shape of a PostHog experiment — the variant split (50\u002F50, 80\u002F20, A\u002FB\u002FC ratios), the overall rollout percentage that gates how many users enter the experiment, and the disambiguation when a percentage like \"roll out to 25%\" could mean either. Use when the user mentions a rollout percentage, variant split, or traffic distribution; gives a ratio like 60\u002F40, 70\u002F30, or 80\u002F20; asks \"who sees the test variant?\"; wants to increase, decrease, or change the rollout or split on a draft or running experiment; weighs equal vs uneven splits; or proposes a mid-experiment split change (often an anti-pattern that needs reset or end-and-restart).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"posthog","PostHog","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fposthog.png",[12,14,17,20],{"name":9,"slug":8,"type":13},"tag",{"name":15,"slug":16,"type":13},"Product Management","product-management",{"name":18,"slug":19,"type":13},"Deployment","deployment",{"name":21,"slug":22,"type":13},"A\u002FB Testing","a-b-testing",59,"https:\u002F\u002Fgithub.com\u002FPostHog\u002Fai-plugin","2026-07-24T05:36:54.187234",null,11,[29,30,31,32],"claude-code-plugin","codex-plugin","cursor-plugin","gemini-cli-extension",{"repoUrl":24,"stars":23,"forks":27,"topics":34,"description":35},[29,30,31,32],"Official PostHog plugin for Claude Code, Cursor, Gemini, Codex and other AI coding tools","https:\u002F\u002Fgithub.com\u002FPostHog\u002Fai-plugin\u002Ftree\u002FHEAD\u002Fskills\u002Fconfiguring-experiment-rollout","---\nname: configuring-experiment-rollout\ndescription: Configures the rollout shape of a PostHog experiment — the variant split (50\u002F50, 80\u002F20, A\u002FB\u002FC ratios), the overall rollout percentage that gates how many users enter the experiment, and the disambiguation when a percentage like \"roll out to 25%\" could mean either. Use when the user mentions a rollout percentage, variant split, or traffic distribution; gives a ratio like 60\u002F40, 70\u002F30, or 80\u002F20; asks \"who sees the test variant?\"; wants to increase, decrease, or change the rollout or split on a draft or running experiment; weighs equal vs uneven splits; or proposes a mid-experiment split change (often an anti-pattern that needs reset or end-and-restart).\n---\n\n# Configuring experiment rollout\n\nThis skill answers: **Who sees what variant?**\n\n## Recommended approach: equal split + adjust rollout percentage\n\nIn most cases, experiments work best with an equal split. If you want to limit exposure to the test variant, adjust the rollout percentage instead.\n\nWhy equal splits are better:\n\n- Equal splits maximize statistical power — each variant has the same sample size\n- Equal splits balance traffic and thus reach significance faster\n- Increasing user exposure throughout the experiment through increasing rollout is clean (changing split mid-experiment can cause users to switch variants, which is bad for user experience and data quality)\n\nAlways default to an equal split unless the user explicitly requests otherwise.\n\n## When an uneven split is required\n\nUneven splits combined with the default \"Exclude multivariate users\" handling can introduce bias.\nIf the experiment observes multi-variant users (users exposed to more than one variant) then those are\ndropped asymmetrically — the smaller variant loses a larger fraction of its assignments. If those users\nbehave differently from the rest, the smaller variant's metrics will be skewed.\n\nThe right mitigation depends on experiment state:\n\n1. **Pre-launch, or live but with few exposures so far — use an equal split and reduce the overall\n   rollout.** Achieves the same test-variant exposure without the bias and preserves statistical\n   power. See the disambiguation question below.\n2. **Live experiment with significant exposures — switch multivariate handling to \"First seen\n   variant\".** Changing the split mid-run reassigns users across variants (anti-pattern; see\n   \"Changing rollout on a running experiment\" below). Switching handling instead keeps everyone in\n   their original variant and avoids the asymmetric exclusion. See `configuring-experiment-analytics`\n   for how to set this. Note that \"first seen\" handling can introduce other biases, but it's\n   preferable to mid-run reassignment.\n\n## The two rollout controls\n\nThere are two separate controls that determine who sees what.\nBoth live on the linked feature flag, sent through the `feature_flag` object in the flag's own shape (not the deprecated `parameters` keys).\n\n### 1. Variant split (`feature_flag.filters.multivariate.variants`)\n\nHow users **inside** the experiment are distributed across variants.\n\n- Array of `{key, name, rollout_percentage}`, where the `rollout_percentage` values must sum to 100\n- Minimum 2 variants, maximum 20\n- No specific variant key is required — the analysis baseline defaults to the variant keyed `\"control\"` when present, else the first variant\n- Default: control 50% \u002F test 50%\n\nIf the user says \"A\u002FB\u002FC test\" without naming keys, key the baseline `\"control\"` (the convention) and create additional variants for the others; if they ask for specific keys, use them as-is with the baseline first.\n\n### 2. Overall rollout (`feature_flag.filters.groups[0].rollout_percentage`)\n\nWhat percentage of **all** users enter the experiment at all, sent as a single rollout group: `groups: [{ \"properties\": [], \"rollout_percentage\": N }]`.\nDefault: 100%.\n\nUsers not included are excluded entirely: they don't see any variant and are **not part of the analysis**.\n\n### Where these are sent\n\nBoth controls live inside `feature_flag.filters`:\n\n```json\n{\n  \"feature_flag\": {\n    \"filters\": {\n      \"multivariate\": {\n        \"variants\": [\n          { \"key\": \"control\", \"name\": \"Control\", \"rollout_percentage\": 50 },\n          { \"key\": \"test\", \"name\": \"Test\", \"rollout_percentage\": 50 }\n        ]\n      },\n      \"groups\": [{ \"properties\": [], \"rollout_percentage\": 100 }]\n    },\n    \"ensure_experience_continuity\": false\n  }\n}\n```\n\n`filters` may also carry `aggregation_group_type_index` (to run the experiment on a group type rather than individual users) and `payloads` (JSON-encoded strings keyed by variant key).\nOn a **running** experiment, any flag-config change must also send `update_feature_flag_params: true`, otherwise the API rejects the update before it reaches the flag (see \"Changing rollout on a running experiment\").\n\n### How they interact\n\nThese two controls multiply:\n\n| Overall rollout | Variant split      | % seeing test | % in analysis |\n| --------------- | ------------------ | ------------- | ------------- |\n| 100%            | 50\u002F50              | 50%           | 100%          |\n| 100%            | 75\u002F25 control\u002Ftest | 25%           | 100%          |\n| 50%             | 50\u002F50              | 25%           | 50%           |\n| 25%             | 50\u002F50              | 12.5%         | 25%           |\n\n## The disambiguation question\n\n**CRITICAL**: If the user requests an uneven variant split (e.g. \"60\u002F40\", \"70\u002F20\u002F10\") or mentions a\nspecific percentage that could refer to either the split or the rollout (e.g. \"roll out to 25%\"), you\nMUST clarify before proceeding. This covers two cases:\n\n### Case 1: Single percentage (\"25%\", \"roll out to 40%\")\n\nThe percentage is ambiguous — it could mean a variant split or a rollout change. Ask:\n\n> There are two ways to get 25% of users seeing the test variant:\n>\n> 1. **Reduced rollout with equal split** (recommended): reduce the overall rollout and split\n>    variants equally. Only a subset of users enter the experiment, and of those, each variant\n>    gets the same share.\n>    Equal splits maximize statistical power and avoid bias.\n> 2. **Asymmetric split**: keep 100% rollout but give the test variant only 25%.\n>    All users enter the experiment, but the uneven split reduces power on the smaller variant\n>    and risks bias.\n>\n> Which approach do you prefer?\n\nAdjust the numbers to match whatever percentage the user requested.\n\n### Case 2: Uneven ratio (\"60\u002F40\", \"70\u002F30\", \"80\u002F20\", etc.)\n\nThe ratio looks like an explicit variant split, but a reduced rollout with an equal split is almost\nalways better. Explain the trade-off and recommend the alternative:\n\n> An uneven variant split works, but an equal split with reduced rollout is recommended:\n>\n> 1. **Equal split + reduced rollout** (recommended): reduce the overall rollout so that the same\n>    fraction of users sees the test variant, but split variants equally within the experiment.\n>    Equal splits maximize statistical power and avoid bias from asymmetric multivariate exclusion.\n> 2. **Uneven split**.\n>    Achieves the same user-facing outcome, but reduces power on the smaller variant and risks bias.\n>\n> Would you like the equal split approach, or do you have a specific reason for the uneven split?\n\nAdjust the numbers to match the ratio. For experiments with more than two variants, \"equal\" means\neach variant gets the same share (e.g. 34\u002F33\u002F33 for three variants). If the user confirms they want\nthe uneven split after seeing the trade-off, proceed — but DO NOT skip the next section.\n\n### After the user picks the uneven split\n\nIf the user proceeds with an uneven split (option 2 in either case above), you MUST surface the\nmultivariate-handling implication BEFORE creating or updating the experiment. The user has chosen\nthe riskier rollout path and needs to make an informed choice about how to mitigate.\n\nAsk:\n\n> One more thing — with an uneven split, the default \"Exclude multivariate users\" handling drops\n> users exposed to multiple variants asymmetrically. The smaller variant loses a larger fraction of\n> its assignments, which can skew its metrics if those users behave differently from the rest.\n>\n> Two options:\n>\n> 1. **Switch multivariate handling to \"First seen variant\"** (recommended for uneven splits) —\n>    keeps all users in the analysis and avoids asymmetric exclusion. Has its own caveats (other\n>    biases can creep in) but is preferable to the default for uneven splits.\n> 2. **Keep the default \"Exclude\" handling** and accept the bias risk.\n>\n> Which would you like?\n\nSee `configuring-experiment-analytics` for how to set the multivariate handling. Apply the choice\nas part of the same operation (creation or update) — do not leave the user with an uneven split\nunder default handling without an explicit, informed decision.\n\n## Persist flag across authentication steps\n\nThis option (`ensure_experience_continuity` on the feature flag) is only relevant when:\n\n- The feature flag is shown to **both** logged-out AND logged-in users\n- You need the same variant assignment before and after login\n\nThis is not compatible with all setups. Learn more: https:\u002F\u002Fposthog.com\u002Fdocs\u002Ffeature-flags\u002Fcreating-feature-flags#persisting-feature-flags-across-authentication-steps\n\nOnly mention this to the user if their use case involves pre\u002Fpost-authentication experiences.\n\n## Resolving experiments\n\nRollout changes require an experiment ID. If the user refers to an experiment by name\nor description (e.g. \"change rollout on my signup test\"), load the `finding-experiments`\nskill to resolve it to a concrete ID before proceeding.\n\n## Changing rollout on a running experiment\n\n**Any change to rollout or variant split on a running experiment affects both user experience and statistical validity.**\nYou MUST warn the user and get explicit confirmation before making the change.\n\nDo NOT silently apply the change — even if the user asked for it directly.\nPresent the warning covering both perspectives:\n\n1. **Who sees what variant?** — will users switch variants or lose a feature?\n2. **Who is in my analysis?** — how does this affect data quality?\n\n**Exception**: Increasing rollout (without changing the split) is generally safe — no users switch variants, more users are added cleanly.\n\n**If the goal is \"stop new users from entering\" rather than a percentage change**: reducing the rollout is the wrong tool — it drops already-enrolled users out of the experiment too.\nFreezing exposure (`experiment-freeze-exposure`) closes enrollment while enrolled users keep their variant and metrics keep flowing; see `managing-experiment-lifecycle` for its preconditions and limitations.\n\n**Mid-experiment fix for uneven-split bias**: switching multivariate handling from \"Exclude\" to \"First\nseen variant\" is the recommended mitigation for already-launched experiments — no users switch variants\nand all collected data stays in the analysis. Changing the split to be even is an anti-pattern mid-run\n(typically requires resetting or ending the experiment) and is only preferred if the experiment hasn't\nbeen exposed to many users yet. See `configuring-experiment-analytics` for how to change the handling.\n\nSee `references\u002Fchanging-distribution-after-launch.md` for detailed warnings, what to tell the user, and when to recommend alternatives.\n",{"data":39,"body":40},{"name":4,"description":6},{"type":41,"children":42},"root",[43,51,63,70,75,80,100,105,111,116,121,154,160,181,196,208,255,267,280,300,312,318,331,814,855,861,866,986,992,1002,1008,1013,1050,1055,1061,1066,1102,1107,1113,1118,1123,1164,1176,1182,1194,1214,1227,1232,1238,1251,1257,1267,1272,1294,1304,1330,1347,1359],{"type":44,"tag":45,"props":46,"children":47},"element","h1",{"id":4},[48],{"type":49,"value":50},"text","Configuring experiment rollout",{"type":44,"tag":52,"props":53,"children":54},"p",{},[55,57],{"type":49,"value":56},"This skill answers: ",{"type":44,"tag":58,"props":59,"children":60},"strong",{},[61],{"type":49,"value":62},"Who sees what variant?",{"type":44,"tag":64,"props":65,"children":67},"h2",{"id":66},"recommended-approach-equal-split-adjust-rollout-percentage",[68],{"type":49,"value":69},"Recommended approach: equal split + adjust rollout percentage",{"type":44,"tag":52,"props":71,"children":72},{},[73],{"type":49,"value":74},"In most cases, experiments work best with an equal split. If you want to limit exposure to the test variant, adjust the rollout percentage instead.",{"type":44,"tag":52,"props":76,"children":77},{},[78],{"type":49,"value":79},"Why equal splits are better:",{"type":44,"tag":81,"props":82,"children":83},"ul",{},[84,90,95],{"type":44,"tag":85,"props":86,"children":87},"li",{},[88],{"type":49,"value":89},"Equal splits maximize statistical power — each variant has the same sample size",{"type":44,"tag":85,"props":91,"children":92},{},[93],{"type":49,"value":94},"Equal splits balance traffic and thus reach significance faster",{"type":44,"tag":85,"props":96,"children":97},{},[98],{"type":49,"value":99},"Increasing user exposure throughout the experiment through increasing rollout is clean (changing split mid-experiment can cause users to switch variants, which is bad for user experience and data quality)",{"type":44,"tag":52,"props":101,"children":102},{},[103],{"type":49,"value":104},"Always default to an equal split unless the user explicitly requests otherwise.",{"type":44,"tag":64,"props":106,"children":108},{"id":107},"when-an-uneven-split-is-required",[109],{"type":49,"value":110},"When an uneven split is required",{"type":44,"tag":52,"props":112,"children":113},{},[114],{"type":49,"value":115},"Uneven splits combined with the default \"Exclude multivariate users\" handling can introduce bias.\nIf the experiment observes multi-variant users (users exposed to more than one variant) then those are\ndropped asymmetrically — the smaller variant loses a larger fraction of its assignments. If those users\nbehave differently from the rest, the smaller variant's metrics will be skewed.",{"type":44,"tag":52,"props":117,"children":118},{},[119],{"type":49,"value":120},"The right mitigation depends on experiment state:",{"type":44,"tag":122,"props":123,"children":124},"ol",{},[125,135],{"type":44,"tag":85,"props":126,"children":127},{},[128,133],{"type":44,"tag":58,"props":129,"children":130},{},[131],{"type":49,"value":132},"Pre-launch, or live but with few exposures so far — use an equal split and reduce the overall\nrollout.",{"type":49,"value":134}," Achieves the same test-variant exposure without the bias and preserves statistical\npower. See the disambiguation question below.",{"type":44,"tag":85,"props":136,"children":137},{},[138,143,145,152],{"type":44,"tag":58,"props":139,"children":140},{},[141],{"type":49,"value":142},"Live experiment with significant exposures — switch multivariate handling to \"First seen\nvariant\".",{"type":49,"value":144}," Changing the split mid-run reassigns users across variants (anti-pattern; see\n\"Changing rollout on a running experiment\" below). Switching handling instead keeps everyone in\ntheir original variant and avoids the asymmetric exclusion. See ",{"type":44,"tag":146,"props":147,"children":149},"code",{"className":148},[],[150],{"type":49,"value":151},"configuring-experiment-analytics",{"type":49,"value":153},"\nfor how to set this. Note that \"first seen\" handling can introduce other biases, but it's\npreferable to mid-run reassignment.",{"type":44,"tag":64,"props":155,"children":157},{"id":156},"the-two-rollout-controls",[158],{"type":49,"value":159},"The two rollout controls",{"type":44,"tag":52,"props":161,"children":162},{},[163,165,171,173,179],{"type":49,"value":164},"There are two separate controls that determine who sees what.\nBoth live on the linked feature flag, sent through the ",{"type":44,"tag":146,"props":166,"children":168},{"className":167},[],[169],{"type":49,"value":170},"feature_flag",{"type":49,"value":172}," object in the flag's own shape (not the deprecated ",{"type":44,"tag":146,"props":174,"children":176},{"className":175},[],[177],{"type":49,"value":178},"parameters",{"type":49,"value":180}," keys).",{"type":44,"tag":182,"props":183,"children":185},"h3",{"id":184},"_1-variant-split-feature_flagfiltersmultivariatevariants",[186,188,194],{"type":49,"value":187},"1. Variant split (",{"type":44,"tag":146,"props":189,"children":191},{"className":190},[],[192],{"type":49,"value":193},"feature_flag.filters.multivariate.variants",{"type":49,"value":195},")",{"type":44,"tag":52,"props":197,"children":198},{},[199,201,206],{"type":49,"value":200},"How users ",{"type":44,"tag":58,"props":202,"children":203},{},[204],{"type":49,"value":205},"inside",{"type":49,"value":207}," the experiment are distributed across variants.",{"type":44,"tag":81,"props":209,"children":210},{},[211,232,237,250],{"type":44,"tag":85,"props":212,"children":213},{},[214,216,222,224,230],{"type":49,"value":215},"Array of ",{"type":44,"tag":146,"props":217,"children":219},{"className":218},[],[220],{"type":49,"value":221},"{key, name, rollout_percentage}",{"type":49,"value":223},", where the ",{"type":44,"tag":146,"props":225,"children":227},{"className":226},[],[228],{"type":49,"value":229},"rollout_percentage",{"type":49,"value":231}," values must sum to 100",{"type":44,"tag":85,"props":233,"children":234},{},[235],{"type":49,"value":236},"Minimum 2 variants, maximum 20",{"type":44,"tag":85,"props":238,"children":239},{},[240,242,248],{"type":49,"value":241},"No specific variant key is required — the analysis baseline defaults to the variant keyed ",{"type":44,"tag":146,"props":243,"children":245},{"className":244},[],[246],{"type":49,"value":247},"\"control\"",{"type":49,"value":249}," when present, else the first variant",{"type":44,"tag":85,"props":251,"children":252},{},[253],{"type":49,"value":254},"Default: control 50% \u002F test 50%",{"type":44,"tag":52,"props":256,"children":257},{},[258,260,265],{"type":49,"value":259},"If the user says \"A\u002FB\u002FC test\" without naming keys, key the baseline ",{"type":44,"tag":146,"props":261,"children":263},{"className":262},[],[264],{"type":49,"value":247},{"type":49,"value":266}," (the convention) and create additional variants for the others; if they ask for specific keys, use them as-is with the baseline first.",{"type":44,"tag":182,"props":268,"children":270},{"id":269},"_2-overall-rollout-feature_flagfiltersgroups0rollout_percentage",[271,273,279],{"type":49,"value":272},"2. Overall rollout (",{"type":44,"tag":146,"props":274,"children":276},{"className":275},[],[277],{"type":49,"value":278},"feature_flag.filters.groups[0].rollout_percentage",{"type":49,"value":195},{"type":44,"tag":52,"props":281,"children":282},{},[283,285,290,292,298],{"type":49,"value":284},"What percentage of ",{"type":44,"tag":58,"props":286,"children":287},{},[288],{"type":49,"value":289},"all",{"type":49,"value":291}," users enter the experiment at all, sent as a single rollout group: ",{"type":44,"tag":146,"props":293,"children":295},{"className":294},[],[296],{"type":49,"value":297},"groups: [{ \"properties\": [], \"rollout_percentage\": N }]",{"type":49,"value":299},".\nDefault: 100%.",{"type":44,"tag":52,"props":301,"children":302},{},[303,305,310],{"type":49,"value":304},"Users not included are excluded entirely: they don't see any variant and are ",{"type":44,"tag":58,"props":306,"children":307},{},[308],{"type":49,"value":309},"not part of the analysis",{"type":49,"value":311},".",{"type":44,"tag":182,"props":313,"children":315},{"id":314},"where-these-are-sent",[316],{"type":49,"value":317},"Where these are sent",{"type":44,"tag":52,"props":319,"children":320},{},[321,323,329],{"type":49,"value":322},"Both controls live inside ",{"type":44,"tag":146,"props":324,"children":326},{"className":325},[],[327],{"type":49,"value":328},"feature_flag.filters",{"type":49,"value":330},":",{"type":44,"tag":332,"props":333,"children":338},"pre",{"className":334,"code":335,"language":336,"meta":337,"style":337},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"feature_flag\": {\n    \"filters\": {\n      \"multivariate\": {\n        \"variants\": [\n          { \"key\": \"control\", \"name\": \"Control\", \"rollout_percentage\": 50 },\n          { \"key\": \"test\", \"name\": \"Test\", \"rollout_percentage\": 50 }\n        ]\n      },\n      \"groups\": [{ \"properties\": [], \"rollout_percentage\": 100 }]\n    },\n    \"ensure_experience_continuity\": false\n  }\n}\n","json","",[339],{"type":44,"tag":146,"props":340,"children":341},{"__ignoreMap":337},[342,354,382,409,436,464,571,670,679,688,762,770,796,805],{"type":44,"tag":343,"props":344,"children":347},"span",{"class":345,"line":346},"line",1,[348],{"type":44,"tag":343,"props":349,"children":351},{"style":350},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[352],{"type":49,"value":353},"{\n",{"type":44,"tag":343,"props":355,"children":357},{"class":345,"line":356},2,[358,363,368,373,377],{"type":44,"tag":343,"props":359,"children":360},{"style":350},[361],{"type":49,"value":362},"  \"",{"type":44,"tag":343,"props":364,"children":366},{"style":365},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[367],{"type":49,"value":170},{"type":44,"tag":343,"props":369,"children":370},{"style":350},[371],{"type":49,"value":372},"\"",{"type":44,"tag":343,"props":374,"children":375},{"style":350},[376],{"type":49,"value":330},{"type":44,"tag":343,"props":378,"children":379},{"style":350},[380],{"type":49,"value":381}," {\n",{"type":44,"tag":343,"props":383,"children":385},{"class":345,"line":384},3,[386,391,397,401,405],{"type":44,"tag":343,"props":387,"children":388},{"style":350},[389],{"type":49,"value":390},"    \"",{"type":44,"tag":343,"props":392,"children":394},{"style":393},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[395],{"type":49,"value":396},"filters",{"type":44,"tag":343,"props":398,"children":399},{"style":350},[400],{"type":49,"value":372},{"type":44,"tag":343,"props":402,"children":403},{"style":350},[404],{"type":49,"value":330},{"type":44,"tag":343,"props":406,"children":407},{"style":350},[408],{"type":49,"value":381},{"type":44,"tag":343,"props":410,"children":412},{"class":345,"line":411},4,[413,418,424,428,432],{"type":44,"tag":343,"props":414,"children":415},{"style":350},[416],{"type":49,"value":417},"      \"",{"type":44,"tag":343,"props":419,"children":421},{"style":420},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[422],{"type":49,"value":423},"multivariate",{"type":44,"tag":343,"props":425,"children":426},{"style":350},[427],{"type":49,"value":372},{"type":44,"tag":343,"props":429,"children":430},{"style":350},[431],{"type":49,"value":330},{"type":44,"tag":343,"props":433,"children":434},{"style":350},[435],{"type":49,"value":381},{"type":44,"tag":343,"props":437,"children":439},{"class":345,"line":438},5,[440,445,451,455,459],{"type":44,"tag":343,"props":441,"children":442},{"style":350},[443],{"type":49,"value":444},"        \"",{"type":44,"tag":343,"props":446,"children":448},{"style":447},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[449],{"type":49,"value":450},"variants",{"type":44,"tag":343,"props":452,"children":453},{"style":350},[454],{"type":49,"value":372},{"type":44,"tag":343,"props":456,"children":457},{"style":350},[458],{"type":49,"value":330},{"type":44,"tag":343,"props":460,"children":461},{"style":350},[462],{"type":49,"value":463}," [\n",{"type":44,"tag":343,"props":465,"children":467},{"class":345,"line":466},6,[468,473,478,484,488,492,496,502,506,511,515,520,524,528,532,537,541,545,549,553,557,561,566],{"type":44,"tag":343,"props":469,"children":470},{"style":350},[471],{"type":49,"value":472},"          {",{"type":44,"tag":343,"props":474,"children":475},{"style":350},[476],{"type":49,"value":477}," \"",{"type":44,"tag":343,"props":479,"children":481},{"style":480},"--shiki-light:#916B53;--shiki-default:#916B53;--shiki-dark:#916B53",[482],{"type":49,"value":483},"key",{"type":44,"tag":343,"props":485,"children":486},{"style":350},[487],{"type":49,"value":372},{"type":44,"tag":343,"props":489,"children":490},{"style":350},[491],{"type":49,"value":330},{"type":44,"tag":343,"props":493,"children":494},{"style":350},[495],{"type":49,"value":477},{"type":44,"tag":343,"props":497,"children":499},{"style":498},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[500],{"type":49,"value":501},"control",{"type":44,"tag":343,"props":503,"children":504},{"style":350},[505],{"type":49,"value":372},{"type":44,"tag":343,"props":507,"children":508},{"style":350},[509],{"type":49,"value":510},",",{"type":44,"tag":343,"props":512,"children":513},{"style":350},[514],{"type":49,"value":477},{"type":44,"tag":343,"props":516,"children":517},{"style":480},[518],{"type":49,"value":519},"name",{"type":44,"tag":343,"props":521,"children":522},{"style":350},[523],{"type":49,"value":372},{"type":44,"tag":343,"props":525,"children":526},{"style":350},[527],{"type":49,"value":330},{"type":44,"tag":343,"props":529,"children":530},{"style":350},[531],{"type":49,"value":477},{"type":44,"tag":343,"props":533,"children":534},{"style":498},[535],{"type":49,"value":536},"Control",{"type":44,"tag":343,"props":538,"children":539},{"style":350},[540],{"type":49,"value":372},{"type":44,"tag":343,"props":542,"children":543},{"style":350},[544],{"type":49,"value":510},{"type":44,"tag":343,"props":546,"children":547},{"style":350},[548],{"type":49,"value":477},{"type":44,"tag":343,"props":550,"children":551},{"style":480},[552],{"type":49,"value":229},{"type":44,"tag":343,"props":554,"children":555},{"style":350},[556],{"type":49,"value":372},{"type":44,"tag":343,"props":558,"children":559},{"style":350},[560],{"type":49,"value":330},{"type":44,"tag":343,"props":562,"children":563},{"style":420},[564],{"type":49,"value":565}," 50",{"type":44,"tag":343,"props":567,"children":568},{"style":350},[569],{"type":49,"value":570}," },\n",{"type":44,"tag":343,"props":572,"children":574},{"class":345,"line":573},7,[575,579,583,587,591,595,599,604,608,612,616,620,624,628,632,637,641,645,649,653,657,661,665],{"type":44,"tag":343,"props":576,"children":577},{"style":350},[578],{"type":49,"value":472},{"type":44,"tag":343,"props":580,"children":581},{"style":350},[582],{"type":49,"value":477},{"type":44,"tag":343,"props":584,"children":585},{"style":480},[586],{"type":49,"value":483},{"type":44,"tag":343,"props":588,"children":589},{"style":350},[590],{"type":49,"value":372},{"type":44,"tag":343,"props":592,"children":593},{"style":350},[594],{"type":49,"value":330},{"type":44,"tag":343,"props":596,"children":597},{"style":350},[598],{"type":49,"value":477},{"type":44,"tag":343,"props":600,"children":601},{"style":498},[602],{"type":49,"value":603},"test",{"type":44,"tag":343,"props":605,"children":606},{"style":350},[607],{"type":49,"value":372},{"type":44,"tag":343,"props":609,"children":610},{"style":350},[611],{"type":49,"value":510},{"type":44,"tag":343,"props":613,"children":614},{"style":350},[615],{"type":49,"value":477},{"type":44,"tag":343,"props":617,"children":618},{"style":480},[619],{"type":49,"value":519},{"type":44,"tag":343,"props":621,"children":622},{"style":350},[623],{"type":49,"value":372},{"type":44,"tag":343,"props":625,"children":626},{"style":350},[627],{"type":49,"value":330},{"type":44,"tag":343,"props":629,"children":630},{"style":350},[631],{"type":49,"value":477},{"type":44,"tag":343,"props":633,"children":634},{"style":498},[635],{"type":49,"value":636},"Test",{"type":44,"tag":343,"props":638,"children":639},{"style":350},[640],{"type":49,"value":372},{"type":44,"tag":343,"props":642,"children":643},{"style":350},[644],{"type":49,"value":510},{"type":44,"tag":343,"props":646,"children":647},{"style":350},[648],{"type":49,"value":477},{"type":44,"tag":343,"props":650,"children":651},{"style":480},[652],{"type":49,"value":229},{"type":44,"tag":343,"props":654,"children":655},{"style":350},[656],{"type":49,"value":372},{"type":44,"tag":343,"props":658,"children":659},{"style":350},[660],{"type":49,"value":330},{"type":44,"tag":343,"props":662,"children":663},{"style":420},[664],{"type":49,"value":565},{"type":44,"tag":343,"props":666,"children":667},{"style":350},[668],{"type":49,"value":669}," }\n",{"type":44,"tag":343,"props":671,"children":673},{"class":345,"line":672},8,[674],{"type":44,"tag":343,"props":675,"children":676},{"style":350},[677],{"type":49,"value":678},"        ]\n",{"type":44,"tag":343,"props":680,"children":682},{"class":345,"line":681},9,[683],{"type":44,"tag":343,"props":684,"children":685},{"style":350},[686],{"type":49,"value":687},"      },\n",{"type":44,"tag":343,"props":689,"children":691},{"class":345,"line":690},10,[692,696,701,705,709,714,718,723,727,731,736,740,744,748,752,757],{"type":44,"tag":343,"props":693,"children":694},{"style":350},[695],{"type":49,"value":417},{"type":44,"tag":343,"props":697,"children":698},{"style":420},[699],{"type":49,"value":700},"groups",{"type":44,"tag":343,"props":702,"children":703},{"style":350},[704],{"type":49,"value":372},{"type":44,"tag":343,"props":706,"children":707},{"style":350},[708],{"type":49,"value":330},{"type":44,"tag":343,"props":710,"children":711},{"style":350},[712],{"type":49,"value":713}," [{",{"type":44,"tag":343,"props":715,"children":716},{"style":350},[717],{"type":49,"value":477},{"type":44,"tag":343,"props":719,"children":720},{"style":447},[721],{"type":49,"value":722},"properties",{"type":44,"tag":343,"props":724,"children":725},{"style":350},[726],{"type":49,"value":372},{"type":44,"tag":343,"props":728,"children":729},{"style":350},[730],{"type":49,"value":330},{"type":44,"tag":343,"props":732,"children":733},{"style":350},[734],{"type":49,"value":735}," [],",{"type":44,"tag":343,"props":737,"children":738},{"style":350},[739],{"type":49,"value":477},{"type":44,"tag":343,"props":741,"children":742},{"style":447},[743],{"type":49,"value":229},{"type":44,"tag":343,"props":745,"children":746},{"style":350},[747],{"type":49,"value":372},{"type":44,"tag":343,"props":749,"children":750},{"style":350},[751],{"type":49,"value":330},{"type":44,"tag":343,"props":753,"children":754},{"style":420},[755],{"type":49,"value":756}," 100",{"type":44,"tag":343,"props":758,"children":759},{"style":350},[760],{"type":49,"value":761}," }]\n",{"type":44,"tag":343,"props":763,"children":764},{"class":345,"line":27},[765],{"type":44,"tag":343,"props":766,"children":767},{"style":350},[768],{"type":49,"value":769},"    },\n",{"type":44,"tag":343,"props":771,"children":773},{"class":345,"line":772},12,[774,778,783,787,791],{"type":44,"tag":343,"props":775,"children":776},{"style":350},[777],{"type":49,"value":390},{"type":44,"tag":343,"props":779,"children":780},{"style":393},[781],{"type":49,"value":782},"ensure_experience_continuity",{"type":44,"tag":343,"props":784,"children":785},{"style":350},[786],{"type":49,"value":372},{"type":44,"tag":343,"props":788,"children":789},{"style":350},[790],{"type":49,"value":330},{"type":44,"tag":343,"props":792,"children":793},{"style":350},[794],{"type":49,"value":795}," false\n",{"type":44,"tag":343,"props":797,"children":799},{"class":345,"line":798},13,[800],{"type":44,"tag":343,"props":801,"children":802},{"style":350},[803],{"type":49,"value":804},"  }\n",{"type":44,"tag":343,"props":806,"children":808},{"class":345,"line":807},14,[809],{"type":44,"tag":343,"props":810,"children":811},{"style":350},[812],{"type":49,"value":813},"}\n",{"type":44,"tag":52,"props":815,"children":816},{},[817,822,824,830,832,838,840,845,847,853],{"type":44,"tag":146,"props":818,"children":820},{"className":819},[],[821],{"type":49,"value":396},{"type":49,"value":823}," may also carry ",{"type":44,"tag":146,"props":825,"children":827},{"className":826},[],[828],{"type":49,"value":829},"aggregation_group_type_index",{"type":49,"value":831}," (to run the experiment on a group type rather than individual users) and ",{"type":44,"tag":146,"props":833,"children":835},{"className":834},[],[836],{"type":49,"value":837},"payloads",{"type":49,"value":839}," (JSON-encoded strings keyed by variant key).\nOn a ",{"type":44,"tag":58,"props":841,"children":842},{},[843],{"type":49,"value":844},"running",{"type":49,"value":846}," experiment, any flag-config change must also send ",{"type":44,"tag":146,"props":848,"children":850},{"className":849},[],[851],{"type":49,"value":852},"update_feature_flag_params: true",{"type":49,"value":854},", otherwise the API rejects the update before it reaches the flag (see \"Changing rollout on a running experiment\").",{"type":44,"tag":182,"props":856,"children":858},{"id":857},"how-they-interact",[859],{"type":49,"value":860},"How they interact",{"type":44,"tag":52,"props":862,"children":863},{},[864],{"type":49,"value":865},"These two controls multiply:",{"type":44,"tag":867,"props":868,"children":869},"table",{},[870,899],{"type":44,"tag":871,"props":872,"children":873},"thead",{},[874],{"type":44,"tag":875,"props":876,"children":877},"tr",{},[878,884,889,894],{"type":44,"tag":879,"props":880,"children":881},"th",{},[882],{"type":49,"value":883},"Overall rollout",{"type":44,"tag":879,"props":885,"children":886},{},[887],{"type":49,"value":888},"Variant split",{"type":44,"tag":879,"props":890,"children":891},{},[892],{"type":49,"value":893},"% seeing test",{"type":44,"tag":879,"props":895,"children":896},{},[897],{"type":49,"value":898},"% in analysis",{"type":44,"tag":900,"props":901,"children":902},"tbody",{},[903,926,947,966],{"type":44,"tag":875,"props":904,"children":905},{},[906,912,917,922],{"type":44,"tag":907,"props":908,"children":909},"td",{},[910],{"type":49,"value":911},"100%",{"type":44,"tag":907,"props":913,"children":914},{},[915],{"type":49,"value":916},"50\u002F50",{"type":44,"tag":907,"props":918,"children":919},{},[920],{"type":49,"value":921},"50%",{"type":44,"tag":907,"props":923,"children":924},{},[925],{"type":49,"value":911},{"type":44,"tag":875,"props":927,"children":928},{},[929,933,938,943],{"type":44,"tag":907,"props":930,"children":931},{},[932],{"type":49,"value":911},{"type":44,"tag":907,"props":934,"children":935},{},[936],{"type":49,"value":937},"75\u002F25 control\u002Ftest",{"type":44,"tag":907,"props":939,"children":940},{},[941],{"type":49,"value":942},"25%",{"type":44,"tag":907,"props":944,"children":945},{},[946],{"type":49,"value":911},{"type":44,"tag":875,"props":948,"children":949},{},[950,954,958,962],{"type":44,"tag":907,"props":951,"children":952},{},[953],{"type":49,"value":921},{"type":44,"tag":907,"props":955,"children":956},{},[957],{"type":49,"value":916},{"type":44,"tag":907,"props":959,"children":960},{},[961],{"type":49,"value":942},{"type":44,"tag":907,"props":963,"children":964},{},[965],{"type":49,"value":921},{"type":44,"tag":875,"props":967,"children":968},{},[969,973,977,982],{"type":44,"tag":907,"props":970,"children":971},{},[972],{"type":49,"value":942},{"type":44,"tag":907,"props":974,"children":975},{},[976],{"type":49,"value":916},{"type":44,"tag":907,"props":978,"children":979},{},[980],{"type":49,"value":981},"12.5%",{"type":44,"tag":907,"props":983,"children":984},{},[985],{"type":49,"value":942},{"type":44,"tag":64,"props":987,"children":989},{"id":988},"the-disambiguation-question",[990],{"type":49,"value":991},"The disambiguation question",{"type":44,"tag":52,"props":993,"children":994},{},[995,1000],{"type":44,"tag":58,"props":996,"children":997},{},[998],{"type":49,"value":999},"CRITICAL",{"type":49,"value":1001},": If the user requests an uneven variant split (e.g. \"60\u002F40\", \"70\u002F20\u002F10\") or mentions a\nspecific percentage that could refer to either the split or the rollout (e.g. \"roll out to 25%\"), you\nMUST clarify before proceeding. This covers two cases:",{"type":44,"tag":182,"props":1003,"children":1005},{"id":1004},"case-1-single-percentage-25-roll-out-to-40",[1006],{"type":49,"value":1007},"Case 1: Single percentage (\"25%\", \"roll out to 40%\")",{"type":44,"tag":52,"props":1009,"children":1010},{},[1011],{"type":49,"value":1012},"The percentage is ambiguous — it could mean a variant split or a rollout change. Ask:",{"type":44,"tag":1014,"props":1015,"children":1016},"blockquote",{},[1017,1022,1045],{"type":44,"tag":52,"props":1018,"children":1019},{},[1020],{"type":49,"value":1021},"There are two ways to get 25% of users seeing the test variant:",{"type":44,"tag":122,"props":1023,"children":1024},{},[1025,1035],{"type":44,"tag":85,"props":1026,"children":1027},{},[1028,1033],{"type":44,"tag":58,"props":1029,"children":1030},{},[1031],{"type":49,"value":1032},"Reduced rollout with equal split",{"type":49,"value":1034}," (recommended): reduce the overall rollout and split\nvariants equally. Only a subset of users enter the experiment, and of those, each variant\ngets the same share.\nEqual splits maximize statistical power and avoid bias.",{"type":44,"tag":85,"props":1036,"children":1037},{},[1038,1043],{"type":44,"tag":58,"props":1039,"children":1040},{},[1041],{"type":49,"value":1042},"Asymmetric split",{"type":49,"value":1044},": keep 100% rollout but give the test variant only 25%.\nAll users enter the experiment, but the uneven split reduces power on the smaller variant\nand risks bias.",{"type":44,"tag":52,"props":1046,"children":1047},{},[1048],{"type":49,"value":1049},"Which approach do you prefer?",{"type":44,"tag":52,"props":1051,"children":1052},{},[1053],{"type":49,"value":1054},"Adjust the numbers to match whatever percentage the user requested.",{"type":44,"tag":182,"props":1056,"children":1058},{"id":1057},"case-2-uneven-ratio-6040-7030-8020-etc",[1059],{"type":49,"value":1060},"Case 2: Uneven ratio (\"60\u002F40\", \"70\u002F30\", \"80\u002F20\", etc.)",{"type":44,"tag":52,"props":1062,"children":1063},{},[1064],{"type":49,"value":1065},"The ratio looks like an explicit variant split, but a reduced rollout with an equal split is almost\nalways better. Explain the trade-off and recommend the alternative:",{"type":44,"tag":1014,"props":1067,"children":1068},{},[1069,1074,1097],{"type":44,"tag":52,"props":1070,"children":1071},{},[1072],{"type":49,"value":1073},"An uneven variant split works, but an equal split with reduced rollout is recommended:",{"type":44,"tag":122,"props":1075,"children":1076},{},[1077,1087],{"type":44,"tag":85,"props":1078,"children":1079},{},[1080,1085],{"type":44,"tag":58,"props":1081,"children":1082},{},[1083],{"type":49,"value":1084},"Equal split + reduced rollout",{"type":49,"value":1086}," (recommended): reduce the overall rollout so that the same\nfraction of users sees the test variant, but split variants equally within the experiment.\nEqual splits maximize statistical power and avoid bias from asymmetric multivariate exclusion.",{"type":44,"tag":85,"props":1088,"children":1089},{},[1090,1095],{"type":44,"tag":58,"props":1091,"children":1092},{},[1093],{"type":49,"value":1094},"Uneven split",{"type":49,"value":1096},".\nAchieves the same user-facing outcome, but reduces power on the smaller variant and risks bias.",{"type":44,"tag":52,"props":1098,"children":1099},{},[1100],{"type":49,"value":1101},"Would you like the equal split approach, or do you have a specific reason for the uneven split?",{"type":44,"tag":52,"props":1103,"children":1104},{},[1105],{"type":49,"value":1106},"Adjust the numbers to match the ratio. For experiments with more than two variants, \"equal\" means\neach variant gets the same share (e.g. 34\u002F33\u002F33 for three variants). If the user confirms they want\nthe uneven split after seeing the trade-off, proceed — but DO NOT skip the next section.",{"type":44,"tag":182,"props":1108,"children":1110},{"id":1109},"after-the-user-picks-the-uneven-split",[1111],{"type":49,"value":1112},"After the user picks the uneven split",{"type":44,"tag":52,"props":1114,"children":1115},{},[1116],{"type":49,"value":1117},"If the user proceeds with an uneven split (option 2 in either case above), you MUST surface the\nmultivariate-handling implication BEFORE creating or updating the experiment. The user has chosen\nthe riskier rollout path and needs to make an informed choice about how to mitigate.",{"type":44,"tag":52,"props":1119,"children":1120},{},[1121],{"type":49,"value":1122},"Ask:",{"type":44,"tag":1014,"props":1124,"children":1125},{},[1126,1131,1136,1159],{"type":44,"tag":52,"props":1127,"children":1128},{},[1129],{"type":49,"value":1130},"One more thing — with an uneven split, the default \"Exclude multivariate users\" handling drops\nusers exposed to multiple variants asymmetrically. The smaller variant loses a larger fraction of\nits assignments, which can skew its metrics if those users behave differently from the rest.",{"type":44,"tag":52,"props":1132,"children":1133},{},[1134],{"type":49,"value":1135},"Two options:",{"type":44,"tag":122,"props":1137,"children":1138},{},[1139,1149],{"type":44,"tag":85,"props":1140,"children":1141},{},[1142,1147],{"type":44,"tag":58,"props":1143,"children":1144},{},[1145],{"type":49,"value":1146},"Switch multivariate handling to \"First seen variant\"",{"type":49,"value":1148}," (recommended for uneven splits) —\nkeeps all users in the analysis and avoids asymmetric exclusion. Has its own caveats (other\nbiases can creep in) but is preferable to the default for uneven splits.",{"type":44,"tag":85,"props":1150,"children":1151},{},[1152,1157],{"type":44,"tag":58,"props":1153,"children":1154},{},[1155],{"type":49,"value":1156},"Keep the default \"Exclude\" handling",{"type":49,"value":1158}," and accept the bias risk.",{"type":44,"tag":52,"props":1160,"children":1161},{},[1162],{"type":49,"value":1163},"Which would you like?",{"type":44,"tag":52,"props":1165,"children":1166},{},[1167,1169,1174],{"type":49,"value":1168},"See ",{"type":44,"tag":146,"props":1170,"children":1172},{"className":1171},[],[1173],{"type":49,"value":151},{"type":49,"value":1175}," for how to set the multivariate handling. Apply the choice\nas part of the same operation (creation or update) — do not leave the user with an uneven split\nunder default handling without an explicit, informed decision.",{"type":44,"tag":64,"props":1177,"children":1179},{"id":1178},"persist-flag-across-authentication-steps",[1180],{"type":49,"value":1181},"Persist flag across authentication steps",{"type":44,"tag":52,"props":1183,"children":1184},{},[1185,1187,1192],{"type":49,"value":1186},"This option (",{"type":44,"tag":146,"props":1188,"children":1190},{"className":1189},[],[1191],{"type":49,"value":782},{"type":49,"value":1193}," on the feature flag) is only relevant when:",{"type":44,"tag":81,"props":1195,"children":1196},{},[1197,1209],{"type":44,"tag":85,"props":1198,"children":1199},{},[1200,1202,1207],{"type":49,"value":1201},"The feature flag is shown to ",{"type":44,"tag":58,"props":1203,"children":1204},{},[1205],{"type":49,"value":1206},"both",{"type":49,"value":1208}," logged-out AND logged-in users",{"type":44,"tag":85,"props":1210,"children":1211},{},[1212],{"type":49,"value":1213},"You need the same variant assignment before and after login",{"type":44,"tag":52,"props":1215,"children":1216},{},[1217,1219],{"type":49,"value":1218},"This is not compatible with all setups. Learn more: ",{"type":44,"tag":1220,"props":1221,"children":1225},"a",{"href":1222,"rel":1223},"https:\u002F\u002Fposthog.com\u002Fdocs\u002Ffeature-flags\u002Fcreating-feature-flags#persisting-feature-flags-across-authentication-steps",[1224],"nofollow",[1226],{"type":49,"value":1222},{"type":44,"tag":52,"props":1228,"children":1229},{},[1230],{"type":49,"value":1231},"Only mention this to the user if their use case involves pre\u002Fpost-authentication experiences.",{"type":44,"tag":64,"props":1233,"children":1235},{"id":1234},"resolving-experiments",[1236],{"type":49,"value":1237},"Resolving experiments",{"type":44,"tag":52,"props":1239,"children":1240},{},[1241,1243,1249],{"type":49,"value":1242},"Rollout changes require an experiment ID. If the user refers to an experiment by name\nor description (e.g. \"change rollout on my signup test\"), load the ",{"type":44,"tag":146,"props":1244,"children":1246},{"className":1245},[],[1247],{"type":49,"value":1248},"finding-experiments",{"type":49,"value":1250},"\nskill to resolve it to a concrete ID before proceeding.",{"type":44,"tag":64,"props":1252,"children":1254},{"id":1253},"changing-rollout-on-a-running-experiment",[1255],{"type":49,"value":1256},"Changing rollout on a running experiment",{"type":44,"tag":52,"props":1258,"children":1259},{},[1260,1265],{"type":44,"tag":58,"props":1261,"children":1262},{},[1263],{"type":49,"value":1264},"Any change to rollout or variant split on a running experiment affects both user experience and statistical validity.",{"type":49,"value":1266},"\nYou MUST warn the user and get explicit confirmation before making the change.",{"type":44,"tag":52,"props":1268,"children":1269},{},[1270],{"type":49,"value":1271},"Do NOT silently apply the change — even if the user asked for it directly.\nPresent the warning covering both perspectives:",{"type":44,"tag":122,"props":1273,"children":1274},{},[1275,1284],{"type":44,"tag":85,"props":1276,"children":1277},{},[1278,1282],{"type":44,"tag":58,"props":1279,"children":1280},{},[1281],{"type":49,"value":62},{"type":49,"value":1283}," — will users switch variants or lose a feature?",{"type":44,"tag":85,"props":1285,"children":1286},{},[1287,1292],{"type":44,"tag":58,"props":1288,"children":1289},{},[1290],{"type":49,"value":1291},"Who is in my analysis?",{"type":49,"value":1293}," — how does this affect data quality?",{"type":44,"tag":52,"props":1295,"children":1296},{},[1297,1302],{"type":44,"tag":58,"props":1298,"children":1299},{},[1300],{"type":49,"value":1301},"Exception",{"type":49,"value":1303},": Increasing rollout (without changing the split) is generally safe — no users switch variants, more users are added cleanly.",{"type":44,"tag":52,"props":1305,"children":1306},{},[1307,1312,1314,1320,1322,1328],{"type":44,"tag":58,"props":1308,"children":1309},{},[1310],{"type":49,"value":1311},"If the goal is \"stop new users from entering\" rather than a percentage change",{"type":49,"value":1313},": reducing the rollout is the wrong tool — it drops already-enrolled users out of the experiment too.\nFreezing exposure (",{"type":44,"tag":146,"props":1315,"children":1317},{"className":1316},[],[1318],{"type":49,"value":1319},"experiment-freeze-exposure",{"type":49,"value":1321},") closes enrollment while enrolled users keep their variant and metrics keep flowing; see ",{"type":44,"tag":146,"props":1323,"children":1325},{"className":1324},[],[1326],{"type":49,"value":1327},"managing-experiment-lifecycle",{"type":49,"value":1329}," for its preconditions and limitations.",{"type":44,"tag":52,"props":1331,"children":1332},{},[1333,1338,1340,1345],{"type":44,"tag":58,"props":1334,"children":1335},{},[1336],{"type":49,"value":1337},"Mid-experiment fix for uneven-split bias",{"type":49,"value":1339},": switching multivariate handling from \"Exclude\" to \"First\nseen variant\" is the recommended mitigation for already-launched experiments — no users switch variants\nand all collected data stays in the analysis. Changing the split to be even is an anti-pattern mid-run\n(typically requires resetting or ending the experiment) and is only preferred if the experiment hasn't\nbeen exposed to many users yet. See ",{"type":44,"tag":146,"props":1341,"children":1343},{"className":1342},[],[1344],{"type":49,"value":151},{"type":49,"value":1346}," for how to change the handling.",{"type":44,"tag":52,"props":1348,"children":1349},{},[1350,1351,1357],{"type":49,"value":1168},{"type":44,"tag":146,"props":1352,"children":1354},{"className":1353},[],[1355],{"type":49,"value":1356},"references\u002Fchanging-distribution-after-launch.md",{"type":49,"value":1358}," for detailed warnings, what to tell the user, and when to recommend alternatives.",{"type":44,"tag":1360,"props":1361,"children":1362},"style",{},[1363],{"type":49,"value":1364},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1366,"total":1539},[1367,1386,1398,1411,1424,1439,1455,1472,1486,1501,1511,1529],{"slug":1368,"name":1368,"fn":1369,"description":1370,"org":1371,"tags":1372,"stars":1383,"repoUrl":1384,"updatedAt":1385},"analyzing-expensive-users","analyze expensive users in AI observability","Analyze the most expensive users in AI observability and explain why they cost so much. Use when the user asks about top spenders, expensive users, per-user LLM cost, user-level cost drivers, or patterns behind high AI observability spend.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1373,1376,1379,1382],{"name":1374,"slug":1375,"type":13},"Analytics","analytics",{"name":1377,"slug":1378,"type":13},"Cost Optimization","cost-optimization",{"name":1380,"slug":1381,"type":13},"Observability","observability",{"name":9,"slug":8,"type":13},35568,"https:\u002F\u002Fgithub.com\u002FPostHog\u002Fposthog","2026-07-28T05:34:11.117757",{"slug":1387,"name":1387,"fn":1388,"description":1389,"org":1390,"tags":1391,"stars":1383,"repoUrl":1384,"updatedAt":1397},"auditing-endpoints","audit PostHog project endpoints","Audit every endpoint in a PostHog project for staleness, failed materialisations, and unused materialised versions. Use when the user asks \"what endpoints can I clean up?\", \"are any of my endpoints broken?\", \"which materialised versions are still being called?\", or wants a one-shot cleanup pass over the Endpoints product. Produces a prioritised report grouped by issue type, with recommended actions but does not modify anything without explicit confirmation.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1392,1393,1396],{"name":1374,"slug":1375,"type":13},{"name":1394,"slug":1395,"type":13},"Audit","audit",{"name":9,"slug":8,"type":13},"2026-06-08T08:08:33.693989",{"slug":1399,"name":1399,"fn":1400,"description":1401,"org":1402,"tags":1403,"stars":1383,"repoUrl":1384,"updatedAt":1410},"auditing-warehouse-source-health","audit PostHog data warehouse source health","Audit the health of a PostHog project's data warehouse sources and syncs — find every broken or degraded source connection, sync schema, and webhook channel. Use when the user asks \"why are my imports failing?\", \"what's broken with my sources?\", \"why is my warehouse data stale?\", or wants a one-shot triage of source\u002Fsync health before deciding where to dig in. Produces a prioritized report grouped by severity, with recommended next steps. For materialized-view health use `auditing-warehouse-view-health`; for a single failing sync use `diagnosing-failed-warehouse-syncs`.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1404,1405,1408,1409],{"name":1394,"slug":1395,"type":13},{"name":1406,"slug":1407,"type":13},"Data Warehouse","data-warehouse",{"name":1380,"slug":1381,"type":13},{"name":9,"slug":8,"type":13},"2026-06-18T08:22:57.67984",{"slug":1412,"name":1412,"fn":1413,"description":1414,"org":1415,"tags":1416,"stars":1383,"repoUrl":1384,"updatedAt":1423},"auditing-warehouse-view-health","audit PostHog materialized view health","Audit the health of a PostHog project's materialized views (saved queries) — find every failed materialization and flag unused or stale materialized views that cost storage and compute. Use when the user asks \"which of my views are broken?\", \"why is this materialized view failing?\", \"are any of my views wasting compute?\", or wants a one-shot triage of view health. For source\u002Fsync health use `auditing-warehouse-source-health`.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1417,1418,1419,1422],{"name":1394,"slug":1395,"type":13},{"name":1406,"slug":1407,"type":13},{"name":1420,"slug":1421,"type":13},"Performance","performance",{"name":9,"slug":8,"type":13},"2026-06-18T08:25:10.936787",{"slug":1425,"name":1425,"fn":1426,"description":1427,"org":1428,"tags":1429,"stars":1383,"repoUrl":1384,"updatedAt":1438},"authoring-error-tracking-alerts","author PostHog error tracking alerts","Author error tracking alerts that fire when an issue is created, reopened, or starts spiking. Use when the user asks to set up error notifications, route exceptions to Slack\u002Fwebhook\u002FLinear, or evaluate which error events are worth alerting on. Covers trigger-event selection, integration choice, dedup against existing alerts, and shipping with the canonical message body shape.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1430,1433,1436,1437],{"name":1431,"slug":1432,"type":13},"Alerting","alerting",{"name":1434,"slug":1435,"type":13},"Debugging","debugging",{"name":1380,"slug":1381,"type":13},{"name":9,"slug":8,"type":13},"2026-06-18T08:24:40.318583",{"slug":1440,"name":1440,"fn":1441,"description":1442,"org":1443,"tags":1444,"stars":1383,"repoUrl":1384,"updatedAt":1454},"authoring-log-alerts","author log alerts in PostHog","Author useful, low-noise log alerts on services in a PostHog project. Use when the user asks to set up alerts for their logs, suggest alerts they should add, or evaluate whether a service is worth monitoring. Covers service triage, baseline characterisation, threshold drafting, back-testing via simulate, and shipping with a notification destination.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1445,1446,1449,1450,1453],{"name":1374,"slug":1375,"type":13},{"name":1447,"slug":1448,"type":13},"Monitoring","monitoring",{"name":1380,"slug":1381,"type":13},{"name":1451,"slug":1452,"type":13},"Operations","operations",{"name":9,"slug":8,"type":13},"2026-07-18T05:10:54.430898",{"slug":1456,"name":1456,"fn":1457,"description":1458,"org":1459,"tags":1460,"stars":1383,"repoUrl":1384,"updatedAt":1471},"building-workflows","build and edit PostHog workflows","Build, edit, test, enable, and monitor PostHog workflows over MCP. Author the action\u002Fedge graph so it runs and opens cleanly in the visual editor, then change drafts surgically with patch operations. Use when asked to build, set up, automate, change, fix, or debug a workflow, campaign, broadcast, drip sequence, or event-triggered automation in the workflows product.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1461,1464,1467,1468],{"name":1462,"slug":1463,"type":13},"Automation","automation",{"name":1465,"slug":1466,"type":13},"MCP","mcp",{"name":9,"slug":8,"type":13},{"name":1469,"slug":1470,"type":13},"Workflow Automation","workflow-automation","2026-07-28T05:34:12.167015",{"slug":1473,"name":1473,"fn":1474,"description":1475,"org":1476,"tags":1477,"stars":1383,"repoUrl":1384,"updatedAt":1485},"check-posthog-loading","inspect PostHog SDK loading across URLs","Inspect how the PostHog JavaScript SDK is loaded across a list of URLs. Use to confirm consistent installation across pages, find pages missing the snippet, detect mismatched API keys or hosts between pages, and verify the load method (head snippet vs deferred vs array.js).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1478,1479,1480,1483,1484],{"name":1374,"slug":1375,"type":13},{"name":1434,"slug":1435,"type":13},{"name":1481,"slug":1482,"type":13},"Frontend","frontend",{"name":1380,"slug":1381,"type":13},{"name":9,"slug":8,"type":13},"2026-05-07T05:56:19.828048",{"slug":1487,"name":1487,"fn":1488,"description":1489,"org":1490,"tags":1491,"stars":1383,"repoUrl":1384,"updatedAt":1500},"consuming-endpoints-from-client-code","integrate PostHog endpoints into client applications","Wire a PostHog endpoint into a client app or SDK. Covers fetching the OpenAPI spec, generating a typed client with openapi-generator or @hey-api\u002Fopenapi-ts, sending the right auth header, shaping the variables payload (HogQL code_name vs insight breakdown property), handling rate-limit and materialised-endpoint error responses. Use when the user says \"how do I call my endpoint\", \"generate a client for this\", or \"what auth header do I use\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1492,1495,1496,1497],{"name":1493,"slug":1494,"type":13},"API Development","api-development",{"name":1481,"slug":1482,"type":13},{"name":9,"slug":8,"type":13},{"name":1498,"slug":1499,"type":13},"SDK","sdk","2026-06-08T08:08:34.929454",{"slug":1502,"name":1502,"fn":1503,"description":1504,"org":1505,"tags":1506,"stars":1383,"repoUrl":1384,"updatedAt":1510},"copying-endpoints-across-projects","copy PostHog endpoints across projects","Copy a PostHog endpoint (a saved HogQL\u002Finsight query exposed as an API route) to another project in the same organization, or duplicate it under a new name in the same project. Use when the user wants to duplicate an endpoint, promote an endpoint from staging to production, replicate an endpoint's query\u002Fvariables\u002Ffreshness config in another workspace, or clone an endpoint to iterate on it. Unlike feature flags and experiments, endpoints have NO native cross-project copy tool — this skill covers the read-then-recreate flow (endpoint-get then endpoint-create), the active-project switching it requires, name-collision checks, and the safe defaults (land unmaterialised in the target, verify with endpoint-run). Does not cover editing endpoint versions (see managing-endpoint-versions) or authoring a brand-new endpoint from scratch (see creating-an-endpoint).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1507,1508,1509],{"name":1493,"slug":1494,"type":13},{"name":1451,"slug":1452,"type":13},{"name":9,"slug":8,"type":13},"2026-07-15T05:29:58.442727",{"slug":1512,"name":1512,"fn":1513,"description":1514,"org":1515,"tags":1516,"stars":1383,"repoUrl":1384,"updatedAt":1528},"creating-ai-subscription","schedule recurring AI-generated PostHog reports","Create a recurring AI-generated PostHog report — schedule a free-text prompt to run on a cron, with the LLM-synthesized markdown delivered to email or Slack on each tick. Use when the user wants a recurring AI summary of X on any cadence (daily, weekly, monthly, yearly) rather than a one-off report. (To attach an AI summary to an existing insight\u002Fdashboard subscription instead of a free-text prompt, see `managing-subscriptions` and its `summary_enabled` option.)\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1517,1518,1521,1522,1525],{"name":1462,"slug":1463,"type":13},{"name":1519,"slug":1520,"type":13},"Email","email",{"name":9,"slug":8,"type":13},{"name":1523,"slug":1524,"type":13},"Reporting","reporting",{"name":1526,"slug":1527,"type":13},"Slack","slack","2026-06-09T07:32:27.935712",{"slug":1530,"name":1530,"fn":1531,"description":1532,"org":1533,"tags":1534,"stars":1383,"repoUrl":1384,"updatedAt":1538},"creating-an-endpoint","create PostHog API endpoints","Create a PostHog endpoint with the right shape on the first try — covers query kind choice, name conventions, what to expose as variables (HogQL code_name vs insight breakdown), data_freshness_seconds, and whether to materialise on day one. Use when the user says \"create an endpoint\", \"expose this query as an API\", \"turn this insight into an endpoint\", or asks for help structuring a new endpoint. Steers away from common mistakes: materialising a query with cohort breakdowns or compare mode, inline-only variables on a materialised endpoint, unbounded date ranges, ambiguous names.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1535,1536,1537],{"name":1374,"slug":1375,"type":13},{"name":1493,"slug":1494,"type":13},{"name":9,"slug":8,"type":13},"2026-06-08T08:08:29.624498",231,{"items":1541,"total":1643},[1542,1557,1571,1586,1599,1611,1627],{"slug":1543,"name":1543,"fn":1544,"description":1545,"org":1546,"tags":1547,"stars":23,"repoUrl":24,"updatedAt":1556},"analyzing-experiment-session-replays","analyze session replays for PostHog experiments","Analyze session replay patterns across experiment variants to understand user behavior differences. Use when the user wants to see how users interact with different experiment variants, identify usability issues, compare behavior patterns between control and test groups, or get qualitative insights to complement quantitative experiment results.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1548,1549,1552,1553],{"name":1374,"slug":1375,"type":13},{"name":1550,"slug":1551,"type":13},"Design","design",{"name":9,"slug":8,"type":13},{"name":1554,"slug":1555,"type":13},"User Research","user-research","2026-04-06T18:44:38.291781",{"slug":1558,"name":1558,"fn":1559,"description":1560,"org":1561,"tags":1562,"stars":23,"repoUrl":24,"updatedAt":1570},"assessing-heatmaps","analyze page heatmaps and suggest improvements","Assesses what a page's heatmap is telling you and recommends concrete changes. Pulls click \u002F rageclick \u002F scroll-depth data for a URL, names the hot elements by cross-referencing autocapture events on the same page, and can create a saved heatmap the user opens in PostHog, then summarizes the behavior and proposes improvements.\nTRIGGER when: user asks what a heatmap shows, why people aren't clicking something, where users rage-click, how far they scroll, what to change on a page based on heatmap\u002Fclick data, or to 'analyze\u002Fassess\u002Freview the heatmap' for a URL.\nDO NOT TRIGGER when: the user only wants to create a saved heatmap screenshot with no analysis (use heatmaps-saved-create directly), or is asking about session replay in general (use investigating-replay).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1563,1564,1565,1566,1567],{"name":1374,"slug":1375,"type":13},{"name":1481,"slug":1482,"type":13},{"name":9,"slug":8,"type":13},{"name":15,"slug":16,"type":13},{"name":1568,"slug":1569,"type":13},"UX Design","ux-design","2026-06-05T07:40:43.37798",{"slug":1572,"name":1572,"fn":1573,"description":1574,"org":1575,"tags":1576,"stars":23,"repoUrl":24,"updatedAt":1585},"auditing-experiments-flags","audit PostHog experiments and feature flags","Audit PostHog experiments and feature flags for configuration issues, staleness, and best-practice violations. Read when the user asks to audit, health-check, or review experiments or feature flags, check flag hygiene, or verify experiment setup.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1577,1578,1581,1582],{"name":1394,"slug":1395,"type":13},{"name":1579,"slug":1580,"type":13},"Feature Flags","feature-flags",{"name":9,"slug":8,"type":13},{"name":1583,"slug":1584,"type":13},"QA","qa","2026-04-06T18:44:30.657553",{"slug":1587,"name":1587,"fn":1588,"description":1589,"org":1590,"tags":1591,"stars":23,"repoUrl":24,"updatedAt":1598},"authoring-scouts","author and edit PostHog Signals scouts","How to author, edit, and adapt PostHog Signals scouts — the scheduled agents that scan a project and write reports into the Signals inbox. Use when a user wants to customize a canonical scout for their own setup (narrow its scope, retune its thresholds, add disqualifiers), tweak a scout's schedule or dry-run posture, or write a brand-new scout from scratch for a specific use case (a custom event, a product surface no canonical scout covers), or steer a scout without editing it at all by leaving it a note. Covers the scout SKILL.md anatomy, the report contract, the dedupe + scratchpad-memory conventions, the scout-notes steering channel, the per-team skills-store path vs the canonical in-repo path, and the write-and-inspect test loop (with dry-run as an optional safety net). Trigger on \"write\u002Fedit\u002Fcustomize a signals scout\", \"new scout for X\", \"tune my scout schedule\", \"make a scout that watches \u003Cevent>\", \"leave a note for \u002F give feedback to a scout\", \"tell the scouts about X\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1592,1595,1596,1597],{"name":1593,"slug":1594,"type":13},"Agents","agents",{"name":1462,"slug":1463,"type":13},{"name":1380,"slug":1381,"type":13},{"name":9,"slug":8,"type":13},"2026-07-28T05:33:45.509154",{"slug":1600,"name":1600,"fn":1601,"description":1602,"org":1603,"tags":1604,"stars":23,"repoUrl":24,"updatedAt":1610},"building-a-dashboard","build and update PostHog dashboards","Build a new dashboard, or update an existing one, from a set of insights — the same job the in-app assistant does with its upsert-dashboard tool, but over MCP. Use when a user asks to create a dashboard, put several metrics\u002Fcharts together on one page, assemble a dashboard for a topic (product analytics, retention, revenue, activation, etc.), or add\u002Fremove\u002Freplace insights on a dashboard they already have. Covers deciding create vs update, reusing existing insights vs creating new ones, and using PostHog's vetted dashboard templates as reference for what a strong dashboard on a topic looks like.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1605,1606,1609],{"name":1374,"slug":1375,"type":13},{"name":1607,"slug":1608,"type":13},"Dashboards","dashboards",{"name":1465,"slug":1466,"type":13},"2026-07-21T06:07:38.060598",{"slug":1612,"name":1612,"fn":1613,"description":1614,"org":1615,"tags":1616,"stars":23,"repoUrl":24,"updatedAt":1626},"checking-deploy-timing","correlate PostHog deployments with GitHub commits","Determine when a PostHog code change reached a given environment by reading the hidden GIT deploy annotations in the project and correlating them with the merge commit on GitHub. Use when PostHog staff ask \"when was X deployed\", \"is my change live in the US\u002FEU yet\", \"has my PR shipped\", \"did the fix roll out to prod-us\", or otherwise want to know whether\u002Fwhen a commit, PR, or feature went out to a region. Do not answer deploy-timing questions from event\u002Fdata volume alone — that only shows when data changed, not when code shipped.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1617,1618,1621,1624,1625],{"name":18,"slug":19,"type":13},{"name":1619,"slug":1620,"type":13},"Git","git",{"name":1622,"slug":1623,"type":13},"GitHub","github",{"name":1380,"slug":1381,"type":13},{"name":9,"slug":8,"type":13},"2026-06-28T07:46:59.53536",{"slug":1628,"name":1628,"fn":1629,"description":1630,"org":1631,"tags":1632,"stars":23,"repoUrl":24,"updatedAt":1642},"choosing-trend-or-slope-view","visualize trends and growth over time","Clarify how to visualize change over a time range before building a trend. Use whenever the user asks how much something changed, grew, dropped, improved, or regressed between two points or periods — \"how much did X change from A to B\", \"before vs after\", \"start vs end\", \"week over week\", \"compare this month to last\", \"change over time\" — or mentions a \"slope chart\" \u002F \"slopegraph\". Two readings of \"change\" need different charts: the whole trend (a line, every interval) versus just the two endpoints (a slope, start vs end). Ask which they want, then render it. Not for choosing a saved insight ChartDisplayType in the insight editor.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1633,1634,1637,1640,1641],{"name":1374,"slug":1375,"type":13},{"name":1635,"slug":1636,"type":13},"Charts","charts",{"name":1638,"slug":1639,"type":13},"Data Visualization","data-visualization",{"name":9,"slug":8,"type":13},{"name":1523,"slug":1524,"type":13},"2026-06-18T08:18:57.960157",56]