Repository navigation
Turn on the R8 optimizer for Android #100003
Description
Background
Every Android release build already runs R8, but the current configuration limits it to shrinking only. Two flags disable the rest:
-dontobfuscateis written inproguard-rules.pro.-dontoptimizeis not written anywhere in the codebase. It arrives throughgetDefaultProguardFile('proguard-android.txt')inbuild.gradle, a legacy default file AGP provides.
The recommended proguard-android-optimize.txt differs by exactly two lines: it drops -dontoptimize and adds -allowaccessmodification, which gives the optimizer more freedom to inline across classes.
The R8 Configuration Analyzer, run against the release build, reports:
Shrinking Score: 45.92%
Optimization Score: 0.00%
Obfuscation Score: 0.00%
Since AGP 8.10 these scores ship in machine-readable form (r8.json) in every build uploaded to Play. For apps carrying more than 10 MB of dex, Play flags low scores as a "DEX code optimization" quality issue. This app carries about 50 MB.
Google has announced: "From February 2027, apps and games on Google Play will need to meet minimum optimization requirements. You will need to achieve a minimum of 25% optimization, obfuscation and shrinking for any app uploads to Play Console."
Problem
If the minimum optimization requirements Google announced for February 2027 take effect while our optimization score is 0%, uploads stop meeting Play's technical quality requirements, which per Google "can affect an app's visibility and publishing capabilities on Google Play".
Benefits beyond compliance
Measured on the release build: 3.5 MB less dex on every device (-6.7%) and a 2.3 MB smaller single-architecture package. Performance gains are expected but tertiary here. Google's case studies report large improvements from letting R8 optimize more of an app — Tinder measured 47% fewer slow cold starts. The exact impact on Expensify is unknown until the change ships and will be measured in Sentry after rollout.
Solution
- Change one line in
build.gradle:getDefaultProguardFile('proguard-android.txt')becomesgetDefaultProguardFile('proguard-android-optimize.txt'). AGP 9 drops the legacy file by default, so this line has to change before any future AGP 9 upgrade regardless. - Verify on an adhoc build with an end-to-end pass, covering both Expensify Classic and New Expensify, since both compile into this one binary. Optimization changes runtime behaviour, so a passing build is not enough.
- Roll out staged while watching the Sentry crash rate. The staged rollout is the safety net for anything the end-to-end pass missed. Rollback is reverting the same one line.
- Confirm the new score in Play Console once the release ships. The analyzer already measures it locally at 45.26%, above the 25% floor. (The analyzer needs a newer R8 than AGP 8.11 bundles, so the score comes from a build with that newer R8 swapped in. The size numbers below are from the unmodified toolchain.)
Measured result
Same app code on both sides, on the R8 version that actually ships:
Before After Delta
Dex bytes 52,992,912 49,456,116 -3.5 MB (-6.7%)
APK bytes (arm64) 145,357,451 143,059,602 -2.3 MB (-1.6%)
Follow-ups
The obfuscation score is also 0%, below the same floor. Fixing it means removing -dontobfuscate, which needs different verification, and will be a separate proposal after this one. Further proposals to come: narrowing the keep rules and removing unused ones, baseline profiling.
References
- R8, shrinking, optimization and obfuscation
- ProGuard manual
- Android Gradle Plugin
- "DEX code optimization" Android vitals metric
- R8 Configuration Analyzer
- Play technical quality requirements (February 2027 announcement)
- Tinder case study
Reported in Slack.
Issue Owner
Current Issue Owner: @TaduJRMetadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsHIGH
Activity
mitarachim commentedon Sep 3, 2026
Deploy Blocker #100246 was identified to be related to the PR https://github.com/Expensify/Mobile-Expensify/pull/14097 that attempted to fix this issue.
TaduJR commentedon Sep 3, 2026
Not able to repro on latest main.
Asked @mitarachim for re-verification here #100246 (comment)
mitarachim commentedon Sep 3, 2026
already replied here
jponikarchuk commentedon Sep 3, 2026
Deploy Blocker #100256 was identified to be related to the PR https://github.com/Expensify/Mobile-Expensify/pull/14097 that attempted to fix this issue.
mitarachim commentedon Sep 3, 2026
Deploy Blocker #100258 was identified to be related to the PR https://github.com/Expensify/Mobile-Expensify/pull/14097 that attempted to fix this issue.
TaduJR commentedon Sep 3, 2026
Not able to repo all the above on both emulator and physical device many times over.
jponikarchuk commentedon Sep 3, 2026
Deploy Blocker #100302 was identified to be related to the PR https://github.com/Expensify/Mobile-Expensify/pull/14097 that attempted to fix this issue.
23 remaining items
TaduJR commentedon Oct 17, 2026
@MelvinBot Please remove the Due Payment from issue title
[-][Due for payment 2026-10-21] Turn on the R8 optimizer for Android[/-][+]Turn on the R8 optimizer for Android[/+]MelvinBot commentedon Oct 17, 2026
Done. I removed the
[Due for payment 2026-10-21]prefix. The title is now "Turn on the R8 optimizer for Android".view run
TaduJR commentedon Oct 21, 2026
Friendly bump on the above ones @AndrewGable
Thanks
AndrewGable commentedon Oct 21, 2026
Done!
melvin-bot commentedon Oct 23, 2026
@TaduJR / @mkhutornyi
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.18-1 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
melvin-bot commentedon Oct 26, 2026
@TaduJR Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
melvin-bot commentedon Oct 28, 2026
@TaduJR Huh... This is 4 days overdue. Who can take care of this?
melvin-bot commentedon Oct 30, 2026
@TaduJR Still overdue 6 days?! Let's take care of this!