Flutter Android App Size in 2026: A Size-Review Routine for Solo Developers (App Bundle, Split Debug Info, Shrinking)

By giosaia (GSPTeck) · Published 2026-10-10 · Last verified 2026-10-10

App size is one of those things a solo developer only notices when it's already a problem: a Play Console warning, a user review saying “too big for what it does”, or a release that suddenly grew after adding one plugin. The good news is that a Flutter Android app has a small number of size levers, and most of them are build flags you set once. This is the size-review routine I use for my Flutter and Firebase apps: how to measure properly, where the bytes usually go, the flags worth enabling, and how to keep size from creeping up release after release. Every command and setting below comes from the official Flutter and Android documentation, checked on 2026-10-10.

Measure the right thing first

Flutter's guide to measuring your app's size starts with a warning that's easy to ignore: debug builds are not representative. They include debugging support and aren't optimised, so a debug APK says almost nothing about what users download. Measure release builds only.

Two columns: misleading measurements such as debug builds and universal APKs with all architectures and densities, versus representative ones such as release App Bundles and Play's per-device download size
Measure what users actually download.

The second trap is measuring a universal APK. A single APK that contains native code for every CPU architecture and assets for every screen density is much bigger than what any one device installs. Google Play generates optimised APKs from your Android App Bundle for each device configuration, so the number that matters is the download size per device, which Play Console reports for each release.

Break down where the bytes go

Flutter has a built-in size analysis tool. Per the same docs, you invoke it by passing --analyze-size when building, for example flutter build appbundle --analyze-size. The build records code size usage by Dart package, prints a summary in the terminal, and leaves a *-code-size-analysis_*.json file you can open in the DevTools app size tool for a deeper, tree-style view.

Grid of where Flutter app bytes go: native libraries, the Dart AOT snapshot, assets, Android Java and Kotlin code, plugin resources, and debug info
The usual size contributors.

In my apps, the breakdown usually points to one of four places:

The levers, in the order I apply them

1. Ship an Android App Bundle

Google's App Bundle documentation says that since August 2021 new apps are required to publish with the Android App Bundle on Google Play. The bundle lets Play deliver only the code and resources each device needs, so a phone doesn't download native code for architectures it can't run. Build it with flutter build appbundle, as described in Flutter's Android deployment guide.

2. Split debug info out of the binary

Flutter's obfuscation guide shows building in release mode with --obfuscate and --split-debug-info=/<symbols-directory>. That moves debug symbols out of the app into a symbols directory, and it obfuscates Dart identifiers. Keep the symbol files for every release, because you need them to read obfuscated stack traces; I store them next to the release tag. If you use Crashlytics, upload them as its Flutter docs describe so crash reports stay readable.

3. Turn on code and resource shrinking for the Android side

Android's guide to shrinking, obfuscating and optimising your app recommends enabling both code optimisation and resource shrinking for release builds. On newer Android Gradle Plugin versions this is a single optimization { enable = true } block; on older versions it's isMinifyEnabled = true and isShrinkResources = true in the release build type. Check your AGP version and use the matching form. Then run a full test pass: shrinking can strip classes that are only reached through reflection, and plugins sometimes need keep rules.

4. Audit assets

Four size levers in order: ship an App Bundle, split debug info and keep symbols, enable code and resource shrinking then test, and audit assets and dependencies
Apply the cheap, safe levers first.

5. Audit dependencies

Every package adds code, and some pull in big native SDKs. Once a quarter I look at the size analysis by package and ask, for each of the biggest ones: do I still use it, is there a lighter alternative, and am I importing a whole SDK for one small feature? Removing one unused plugin can do more than an afternoon of image compression.

Keep size from creeping back

Size grows one release at a time, so I treat it as part of the release checklist rather than a one-off project:

Four steps to stop size creep: run analyze-size every release, compare with the previous JSON, set a growth budget, and record Play's download size in the changelog
A per-release habit.
  1. Record the per-device download size from Play Console for every release in your changelog.
  2. Run --analyze-size before any release that adds a dependency and compare it with the previous JSON file.
  3. Set a personal budget, for example “no release grows by more than a few percent without a reason I can name”.
  4. Review Play Console's app size reports; Google's Play Console help on app size explains the limits and the size data Play shows.

This fits naturally next to the other routine checks I run, like the weekly Crashlytics triage and the target API upgrade plan, which itself can change size when you bump AGP and plugins.

A worked routine for one release

Here's how the pieces fit together on a normal release day for one of my apps, without any specific numbers, because yours will differ:

  1. Build the release bundle with --analyze-size, --obfuscate and --split-debug-info, and archive the symbols folder under the version number.
  2. Open the size analysis JSON in DevTools and compare the top packages with the previous release's file.
  3. If something grew, find out why before uploading: a new plugin, a new asset, or a dependency upgrade.
  4. Upload to the internal testing track, install from Play on a real device, and run the screens most likely to break under shrinking.
  5. After rollout, copy Play Console's download size into the changelog.

Common mistakes

FAQ

Why is my Flutter APK so much bigger than the Play download size?

A universal APK includes native code and resources for all devices. Play delivers a smaller, device-specific set generated from your App Bundle.

Does obfuscation make the app smaller?

The main size effect comes from moving debug info out with --split-debug-info; obfuscation itself is mainly about making reverse engineering harder. Measure your own build to see the difference.

Is code shrinking safe for Flutter apps?

Usually, but test thoroughly. Some plugins or SDKs need keep rules, which their documentation normally lists.

How often should I review app size?

Check the number every release and do a deeper dependency and asset audit every few months.

Sources

More guides: the GSPTeck blog.