SSpinosis

How to Name Experiment Keys for Long-Term SDK Maintainability

·Implementation

Name experiment keys by describing what element varies in the test, not what you hope to achieve. A key like "paywall_cta_wording" clearly indicates that button text changes across variants, while "conversion_boost_test" tells future developers nothing about what actually differs in the code. This naming approach makes your SDK calls self-documenting and prevents confusion when multiple experiments target similar goals.

Use a consistent namespace structure that groups related experiments and indicates scope. Prefixes like "onboarding.trial_duration" or "paywall.price_display" create logical hierarchies that help developers understand which part of the app each experiment affects. This structure remains useful months later when you're debugging attribution issues or cleaning up old experiment code that should have been removed.

What makes an experiment key discoverable six months later

Your experiment key appears in multiple places: SDK initialization code, variant assignment logic, analytics events, and attribution pipelines. Six months after launch, a different developer needs to understand what this key controls without archaeological research through Slack threads or experiment documentation that may no longer exist. The key itself should answer "what varies here" at a glance.

Bad keys like "test_42", "new_flow", or "q4_optimization" force developers to trace through conditional logic, guess at intent, or ask around to understand what code paths activate for each variant. Good keys like "subscribe_button_color", "trial_length_days", or "feature_gate_timing" make the variation explicit. When debugging a purchase attribution mismatch, you want to immediately identify which experiment might be interfering, not decrypt ambiguous identifiers.

Namespace structure prevents collision and confusion

As your experimentation program matures, you'll run simultaneous tests across different app surfaces. Without namespacing, keys like "headline_test" could refer to your paywall, onboarding welcome screen, email campaign, or push notification. Prefixing with scope—"paywall.headline_test"—eliminates ambiguity and groups related experiments together in autocomplete and logs.

A consistent hierarchy like "surface.element.property" scales well: "onboarding.welcome.headline", "paywall.annual_plan.discount_badge", "settings.account_deletion.confirmation_steps". This structure makes it obvious which experiments might interact or conflict. If you're testing both "paywall.cta_button" and "paywall.price_position" simultaneously, the naming immediately signals potential interaction effects that a flat namespace would obscure until you notice unexpected results.

Why dates and outcomes make terrible experiment keys

Keys like "jan_2026_test" or "spring_paywall" seem convenient during creation but become cryptic immediately. What did that January test modify? Which element of the spring paywall changed? When you're reviewing experiment history or auditing active tests, temporal names provide zero context about what varied. They also encourage leaving old experiments running indefinitely because no one knows if removing "q3_test" will break something.

Outcome-focused names like "increase_conversion", "reduce_churn", or "boost_revenue" seem descriptive but describe intent, not implementation. Multiple experiments share the same goal, so these names don't differentiate between testing pricing changes versus UI redesigns versus messaging tweaks. When your attribution system shows revenue from "revenue_test_v2", you can't determine which product change drove results without cross-referencing external documentation that may be outdated or missing.

How specificity improves debugging and reduces technical debt

Specific keys make conditional logic self-documenting. Code like "if (experiment.getVariant('paywall_annual_price_display') === 'percentage_savings')" clearly shows what's being tested and what differs between variants. Generic keys like "if (experiment.getVariant('test_5') === 'variant_b')" require looking up external mapping to understand what variant_b actually implements. During code review or incident response, self-documenting keys dramatically reduce cognitive load.

Technical debt accumulates when experiments outlive their usefulness but remain in code because removal feels risky. Clear naming makes it obvious when an experiment can be safely removed or graduated to a feature flag. If "onboarding.tutorial_skip_button" ran for three months and you've shipped the winning variant to everyone, you can confidently remove that experiment code. Ambiguous keys like "onboarding_test_3" make developers hesitant to touch anything, leading to cruft that slows down the codebase and complicates future experiments.

Naming conventions for variant values and holdout groups

Variant names should describe their treatment, not arbitrary labels. Instead of "variant_a" and "variant_b", use "control", "7_day_trial", "14_day_trial" for a trial length test. When reviewing analytics or debugging attribution, descriptive variant names make data interpretation immediate. You see conversion rates for "monthly_price_upfront" versus "monthly_price_after_trial" and understand exactly what each group experienced.

For platforms like Spinosis that support holdout groups while shifting traffic to winners, name your holdout explicitly: "original_control_holdout" rather than recycling "control". This distinction matters when analyzing long-term effects—your holdout continues seeing the pre-experiment experience while shifted traffic gets the winner. Clear naming prevents confusion about which users received which treatment when reviewing historical purchase attribution data, especially when experiments overlap or evolve over time.

Questions

Should experiment keys match the analytics event names I send?

Not necessarily, but they should be clearly related. Your experiment key might be "paywall.price_position" while your analytics event is "paywall_viewed" with a property "price_position_variant". The key identifies the experiment in your SDK; the event tracks user exposure. Maintain a naming convention that makes the relationship obvious—like prefixing analytics properties with the experiment key—so you can easily join experiment assignments with behavioral data during analysis.

How do I name experiments that test multiple elements simultaneously?

Use the most distinctive or impactful element in the key, then document the full treatment in your experiment platform. For example, "onboarding.redesign_v2" signals a comprehensive change while remaining concise in code. Alternatively, if you're testing independent elements that might be separated later, create separate experiment keys even within the same experience. This approach gives you flexibility to graduate individual winners without shipping the entire bundle together.

What naming convention works best for multi-variate tests with many combinations?

Name the experiment for the dimensions being tested, then use variant names that specify each combination. For example, key "paywall.headline_and_cta" with variants like "benefit_headline__subscribe_cta", "feature_headline__start_trial_cta". The double underscore separates dimensions, making combinations parsable by both humans and automated analysis. This approach scales better than creating separate keys for each combination, which would explode your namespace and complicate traffic allocation logic.

Turn on auto-optimize for one test.

Create a project, install the SDK, connect RevenueCat. Traffic starts shifting on its own.

Related guides