Types of Feature Toggles

Feature Toggles (or Flags) let you change system behavior without modifying code. While they enable rapid and safe delivery of new features, they introduce complexity. Careful management, good practices, the right tools, and limiting the number of active toggles are crucial to keep this complexity under control.

This lesson explores different types of feature toggles, their categorization, and their application in Flutter development. Upcoming lessons will delve into implementation details, best practices, and practical tips for using feature toggles and A/B testing in Flutter.


Categories of Toggles

Feature toggles enable deploying alternative code paths and selecting between them at runtime. However, not all toggles are the same—different types require different management approaches.

Two key factors in categorizing feature toggles are longevity (how long they exist) and dynamism (how frequently their state changes).

Let’s review the different types of feature toggles based on these two dimensions. 👇

Release Toggles

Release toggles enable trunk-based development for teams using Continuous Delivery. They allow developers to merge in-progress features into a shared branch (e.g., main or trunk) while keeping the branch deployable at all times. This means unfinished or untested code can be shipped to production without being activated, ensuring safe and continuous deployments.

  • Flutter Example: Hide an unfinished feature behind a flag stored as a hardcoded value in your Dart code.

Ops Toggles

Ops toggles control operational aspects of the system. They are useful for rolling out features with uncertain performance impact, allowing operators to quickly disable or degrade features quickly as a safeguard against unexpected production issues.

  • Flutter Examples:
    • Use Firebase Remote Config to dynamically disable a performance-heavy feature.
    • Immediately disable a feature causing a sudden cost spike (for apps using a BaaS).

Experiment Toggles

Experiment toggles support A/B testing and multivariate experiments. Users are assigned to different cohorts, and the system routes them through different code paths based on their assigned group. Tracking user behavior across cohorts helps teams make data-driven decisions, like optimizing e-commerce checkout flows or testing different call-to-action (CTA) button variations.

  • Flutter Example: Use Firebase Remote Config and Analytics to test paywalls by customizing CTA button text or color and measuring user reactions to different pricing options.

Permission Toggles

Permission toggles manage feature access based on user type. They can be used to grant premium features to paying customers, early access to internal testers, or beta features to selected users, controlling the user experience based on subscriptions, roles, or testing phases.

  • Flutter Examples: Use Firebase Authentication and Firestore to check if a user has access to a premium feature.

Longevity and Dynamism

Feature toggles differ in how long they last (longevity) and how often their state changes (dynamism):

Types of toggles (by longevity and dynamism)
  • Permission Toggles (e.g., premium user access) are long-lived (years) and highly dynamic, as access is determined per request.
  • Experiment Toggles (for A/B testing) are moderately dynamic, assigning users to groups at runtime, often using cohort-based algorithms.
  • Release Toggles (for unfinished features) are short-lived (days/weeks) and mostly static, often just checking a simple on/off state.
  • Ops Toggles (for performance or stability) can be short- or long-lived but tend to be static, changing only when operators manually adjust them.

These differences impact implementation: static toggles can use simple on/off states, while dynamic toggles require more advanced routing logic. Long-lived toggles should be structured for maintainability, avoiding scattered if/else checks.

Implementation Complexity

As we will see in the upcoming lessons, certain types of toggles are more complex to implement than others:

  • Release toggles can be as simple as a hardcoded boolean in your code, set to false to hide an unfinished feature in production builds.
  • Experiment toggles, however, require a more advanced setup, potentially including:
    • A remote config flag loaded dynamically at runtime.
    • Firebase Analytics to track user behavior across cohorts.
    • Running an A/B test over time to determine the better-performing variant.
    • Gradually rolling out the winning variant to more users.

Implementation complexity increases with toggle dynamism and longevity, demanding better tooling and management strategies.

Drawbacks of Feature Toggles

While useful, feature toggles add complexity to the codebase, requiring explicit branching logic for incomplete features. This can lead to messy code if old flags aren’t retired. Testers may struggle with the concept of shipping unfinished code to the app store. Additionally, if flags are controlled remotely, teams must ensure new configurations are tested before deployment to end users.


Question 1 of 3

What are the key characteristics of Static Release Toggles?

Wrap Up and Next Steps

In this lesson, we explored different types of feature toggles and their categorization based on longevity and dynamism.

Next, we’ll explore some of these toggle types in more detail and dive deeper into implementation specifics.


Resources

Questions? Let's chat