Staged Rollouts
What is a Staged Rollout
A staged rollout gradually exposes a new version to an increasing percentage of users. Instead of releasing to 100% of users at once, you start with 1-5%, monitor crash rates and user feedback, and increase the percentage as confidence grows.
Rollout Stages
A typical staged rollout follows this pattern:
| Stage | Percentage | Duration | Focus |
|---|---|---|---|
| Canary | 1-5% | 1-2 hours | Crash rate, ANR rate |
| Early adopters | 5-20% | 1-2 days | User feedback, edge cases |
| Broad rollout | 20-50% | 2-3 days | Performance metrics |
| Full release | 50-100% | 1-2 days | Stable state |
Implementing in Play Console
When publishing a new version:
- Go to Release > Production
- Create a new release and upload your AAB
- Set the rollout percentage to your starting value (e.g., 5%)
- Monitor the Android Vitals dashboard for crash rates
- Increase the percentage when metrics are stable
- If issues arise, use Halt rollout to stop distribution immediately
Automated Rollout with Fastlane
You can automate percentage increases with fastlane:
# Fastfile
lane :promote_to_production do
# Promote from internal to production at 5%
supply(
track: 'internal',
rollout: '0.05',
package_name: 'com.example.myapp'
)
end
lane :increase_rollout do |options|
supply(
track: 'production',
rollout: options[:percentage],
package_name: 'com.example.myapp'
)
end
Rollout Monitoring
During rollout, watch these metrics:
- Crash-free users — Must remain above 99.5%
- ANR rate — Should be below 0.47%
- User reviews — Spike in negative reviews signals problems
- Uninstalls — Sudden increase indicates a broken release
Feature Flags
What Feature Flags Do
Feature flags (also called feature toggles) decouple code deployment from feature release. You can merge code to production without exposing it to users, then enable it remotely when ready.
Simple Feature Flag Implementation
A basic feature flag system using SharedPreferences or a remote config:
class FeatureFlags(private val context: Context) {
private val prefs = context.getSharedPreferences("feature_flags", Context.MODE_PRIVATE)
fun isEnabled(flag: String): Boolean {
return prefs.getBoolean(flag, false)
}
fun setEnabled(flag: String, enabled: Boolean) {
prefs.edit().putBoolean(flag, enabled).apply()
}
}
// Usage in a composable
@Composable
fun HomeScreen(featureFlags: FeatureFlags) {
if (featureFlags.isEnabled("new_checkout_flow")) {
NewCheckoutScreen()
} else {
LegacyCheckoutScreen()
}
}
Remote Feature Flags with Firebase Remote Config
For server-controlled flags without app updates:
val remoteConfig = Firebase.remoteConfig
val configSettings = remoteConfigSettings {
minimumFetchIntervalInSeconds = 3600 // 1 hour in production
}
remoteConfig.setConfigSettingsAsync(configSettings)
// Set defaults
remoteConfig.setDefaultsAsync(mapOf(
"new_checkout_flow" to false,
"dark_mode_enabled" to true
))
// Fetch and activate
remoteConfig.fetchAndActivate().addOnCompleteListener {
if (it.isSuccessful) {
val newCheckout = remoteConfig.getBoolean("new_checkout_flow")
// Apply the flag
}
}
Kill Switch Pattern
Use feature flags as kill switches for problematic features:
// In your network layer
val experimentalApiEnabled = Firebase.remoteConfig.getBoolean("experimental_api")
if (experimentalApiEnabled) {
return experimentalApiClient.getData()
} else {
return legacyApiClient.getData()
}
If the new API causes issues, disable it remotely without an app update.
Flag Lifecycle
Feature flags should be temporary. Follow a cleanup process:
- Create — Add the flag with a default value
- Roll out — Enable for percentage of users
- Confirm — Verify metrics and user feedback
- Cleanup — Remove the flag and dead code branches
Long-lived flags accumulate technical debt. Assign owners and set expiration dates.
A/B Testing
What A/B Testing Means
A/B testing compares two or more variants to determine which performs better. Users are randomly assigned to variants, and a primary metric determines the winner. This replaces opinion-based decisions with data.
Setting Up A/B Tests with Firebase
Firebase Remote Config supports A/B testing through Firebase Experiments:
- Open Firebase Console > Remote Config
- Create a new parameter with conditional values
- Create an A/B test linking the parameter to an audience
- Define the success metric (conversion rate, engagement, retention)
Anatomy of a Good A/B Test
Every test needs:
- Hypothesis — "Changing the checkout button color from gray to green will increase conversion by 5%"
- Control — The current version (button = gray)
- Variant — The new version (button = green)
- Primary metric — Checkout completion rate
- Secondary metrics — Revenue, session length, crash rate
- Minimum sample size — Calculate using statistical significance tools
Example A/B Test Implementation
// In your composable
@Composable
fun CheckoutButton(firebaseRemoteConfig: FirebaseRemoteConfig) {
val buttonColor = if (firebaseRemoteConfig.getBoolean("checkout_green_button")) {
Color(0xFF4CAF50) // Green variant
} else {
Color(0xFF9E9E9E) // Gray control
}
Button(
onClick = { /* checkout logic */ },
colors = ButtonDefaults.buttonColors(containerColor = buttonColor)
) {
Text("Complete Purchase")
}
}
Interpreting Results
Wait for statistical significance before declaring a winner:
- p-value < 0.05 — Results are statistically significant
- Confidence interval — Shows the range of likely effect sizes
- Segment analysis — Check if results hold across user segments
Common pitfalls:
- Stopping tests too early when one variant is ahead
- Testing too many variants with insufficient traffic
- Ignoring secondary metrics (a button change might increase conversions but hurt retention)
Release Strategy Integration
Combine all three techniques:
- Feature flag — Merge code with the flag off
- A/B test — Enable the flag for a test audience, measure impact
- Staged rollout — If the variant wins, roll out to all users gradually
This pipeline minimizes risk at every stage.
Quiz
1. What is the primary benefit of a staged rollout?
2. Why should feature flags be temporary?
3. What statistical threshold typically indicates an A/B test result is significant?
4. What is a kill switch in the context of feature flags?
Flashcards
Question
What are the four typical stages of a staged rollout?
Click to reveal answer
Answer
Canary (1-5%, 1-2 hours), Early adopters (5-20%, 1-2 days), Broad rollout (20-50%, 2-3 days), Full release (50-100%, 1-2 days).
Question
What is a feature flag's kill switch pattern?
Click to reveal answer
Answer
A remotely controlled feature toggle that can immediately disable a problematic feature without requiring an app update or Play Store submission.
Question
What is the purpose of the hypothesis in an A/B test?
Click to reveal answer
Answer
It defines the expected outcome and primary metric before the test starts, preventing data mining and post-hoc rationalization.
Question
What metrics should you monitor during a staged rollout?
Click to reveal answer
Answer
Crash-free users (>99.5%), ANR rate (<0.47%), user reviews, and uninstall rates.
Revision Notes
Key Takeaways
- 1. Staged rollouts limit blast radius by exposing new versions to a small percentage of users first
- 2. Feature flags decouple code deployment from feature release, enabling safe incremental rollouts
- 3. A/B tests replace opinion-based decisions with data; always wait for statistical significance
- 4. Combine feature flags, A/B testing, and staged rollouts into a complete release pipeline
- 5. Monitor crash-free users, ANR rates, and user reviews during every stage of a rollout
Interview Tips
- • Describe how you would safely release a new feature to production
- • Explain the difference between a feature flag and an A/B test
- • Discuss how you would handle a critical bug discovered during a staged rollout
- • Know the metrics to monitor and the thresholds that indicate problems
- • Be prepared to design a complete release pipeline from code merge to full production
Cheat Sheet
Release Strategy Cheat Sheet
Staged Rollout Stages:
- Canary: 1-5% — Monitor crashes
- Early adopters: 5-20% — Check feedback
- Broad: 20-50% — Verify performance
- Full: 50-100% — Stable state
Rollout Metrics:
- Crash-free users: > 99.5%
- ANR rate: < 0.47%
- Uninstall rate: monitor for spikes
Feature Flag Lifecycle:
Create → Roll out → Confirm → Cleanup
A/B Test Requirements:
- Hypothesis
- Control + Variant
- Primary metric
- p-value < 0.05 for significance
- Minimum sample size
Integration Flow:
Feature flag (merge safely) → A/B test (measure impact) → Staged rollout (gradual release)