← Articles

Staged rollouts for Flutter apps on Google Play

By Ann Tech · 6 February 2026

Staged rollouts on Google Play let you release an update to a small percentage of users, watch for crashes and negative reviews, then gradually expand. If something goes wrong, you halt instead of replacing a working release for everyone.

Why staged rollouts matter

No amount of testing catches every device/OS combination. A bug affecting 0.1% of Android devices can mean thousands of crashes at scale. Staged rollouts surface that before it hits everyone.

Configuring in the Play Console

Play Console → Your App → Release → Production → Create new release.

After uploading your AAB, in the "Roll out release" step:

  1. Click "Set rollout percentage"
  2. Set the initial percentage (10% is common)
  3. Submit release

Users are selected randomly and persistently — the same users stay in the rollout as you expand.

Expanding or halting

To expand: Production → Manage rollout → Increase rollout percentage.

To halt: Manage rollout → Halt rollout. Halting stops new users from getting the update but does not roll back existing installs.

Automated rollout with Fastlane

# fastlane/Fastfile
lane :deploy_staged do
  supply(
    track: 'production',
    rollout: '0.1',  # 10%
    aab: 'build/app/outputs/bundle/release/app-release.aab',
    skip_upload_metadata: true,
    skip_upload_images: true,
    skip_upload_screenshots: true,
  )
end

lane :expand_rollout do |options|
  supply(
    track: 'production',
    rollout: options[:percentage] || '0.5',
    skip_upload_apk: true,
    skip_upload_aab: true,
    skip_upload_metadata: true,
    skip_upload_images: true,
    skip_upload_screenshots: true,
  )
end

Usage:

bundle exec fastlane deploy_staged
bundle exec fastlane expand_rollout percentage:0.5   # 50%
bundle exec fastlane expand_rollout percentage:1.0   # 100%

Monitoring during rollout

Android Vitals → Crashes and ANRs — Compare crash rate to previous release. Play flags "bad behaviour" above ~1.09%.

Firebase Crashlytics — Filter by version to isolate new-version crashes:

await FirebaseCrashlytics.instance.setCustomKey(
  'app_build_number',
  packageInfo.buildNumber,
);

Ratings — A sudden spike of 1-star ratings is a signal to halt immediately.

Rollout decision criteria

DayAction
Day 0Release at 10%
Day 1Review metrics. If clean → 25%
Day 2If clean → 50%
Day 3-4If clean → 100%
AnytimeSignificant crash rate increase → Halt

Testing tracks

  • Internal testing: up to 100 testers, instant publish (no review)
  • Closed testing (Alpha): specific testers, requires review
  • Open testing (Beta): public opt-in, requires review
  • Production: all users, staged rollout available
lane :deploy_internal do
  supply(
    track: 'internal',
    aab: 'build/app/outputs/bundle/release/app-release.aab',
  )
end

Version code strategy

Each release needs a unique versionCode:

flutter build appbundle \
  --build-number=$CI_BUILD_NUMBER \
  --build-name=2.5.1

Google Play vs App Store phased release

  • Google Play: you control the percentage manually, can halt at any time.
  • Apple phased release: automatic 7-day rollout (1% → 2% → 5% → 10% → 20% → 50% → 100%). You can pause but can't set a custom percentage.

Common pitfalls

Halting and forgetting. A halted rollout doesn't auto-resume. Check your Play Console weekly for stuck releases.

Treating 10% as safe enough to ignore. 10% of 10,000 daily users is 1,000 users. Low-frequency bugs may not appear in the first 24 hours. Monitor for 48 hours before expanding.

Uploading metadata changes with a rollout. Changing store listing copy while rolling out makes it hard to attribute user behaviour changes. Separate metadata updates from binary updates.

Sign in to like, dislike, or report.

Staged rollouts for Flutter apps on Google Play — ANN Tech