Skip to content

Turn on the R8 optimizer for Android #100003

Open

Description

@melvin-bot

Background

Every Android release build already runs R8, but the current configuration limits it to shrinking only. Two flags disable the rest:

  • -dontobfuscate is written in proguard-rules.pro.
  • -dontoptimize is not written anywhere in the codebase. It arrives through getDefaultProguardFile('proguard-android.txt') in build.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

  1. Change one line in build.gradle: getDefaultProguardFile('proguard-android.txt') becomes getDefaultProguardFile('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.
  2. 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.
  3. 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.
  4. 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

Related: #99839, #98008

Reported in Slack.

Issue OwnerCurrent Issue Owner: @TaduJR

Activity

  1. self-assigned this
    on Sep 1, 2026
  2. removed their assignment
    on Sep 2, 2026
  3. mitarachim commented on Sep 3, 2026

    @mitarachim

    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.

  4. TaduJR commented on Sep 3, 2026

    @TaduJR
    Contributor

    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.

    Not able to repro on latest main.

    Asked @mitarachim for re-verification here #100246 (comment)

  5. mitarachim commented on Sep 3, 2026

    @mitarachim

    already replied here

  6. jponikarchuk commented on Sep 3, 2026

    @jponikarchuk

    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.

  7. mitarachim commented on Sep 3, 2026

    @mitarachim

    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.

  8. TaduJR commented on Sep 3, 2026

    @TaduJR
    Contributor

    Not able to repo all the above on both emulator and physical device many times over.

  9. jponikarchuk commented on Sep 3, 2026

    @jponikarchuk

    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.

  10. 23 remaining items

  11. TaduJR commented on Oct 17, 2026

    @TaduJR
    Contributor

    @MelvinBot Please remove the Due Payment from issue title

  12. changed the title [-][Due for payment 2026-10-21] Turn on the R8 optimizer for Android[/-] [+]Turn on the R8 optimizer for Android[/+] on Oct 17, 2026
  13. MelvinBot commented on Oct 17, 2026

    @MelvinBot
    Contributor

    Done. I removed the [Due for payment 2026-10-21] prefix. The title is now "Turn on the R8 optimizer for Android".


    view run

  14. TaduJR commented on Oct 21, 2026

    @TaduJR
    Contributor

    Friendly bump on the above ones @AndrewGable

    Thanks

  15. AndrewGable commented on Oct 21, 2026

    @AndrewGable
    Contributor

    Done!

  16. melvin-bot commented on Oct 23, 2026

    @melvin-bot
    Author

    @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:

  17. melvin-bot commented on Oct 26, 2026

    @melvin-bot
    Author

    @TaduJR Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

  18. melvin-bot commented on Oct 28, 2026

    @melvin-bot
    Author

    @TaduJR Huh... This is 4 days overdue. Who can take care of this?

  19. melvin-bot commented on Oct 30, 2026

    @melvin-bot
    Author

    @TaduJR Still overdue 6 days?! Let's take care of this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

DailyKSv2OverdueSkip PaymentSkips all the payment process steps for an issue. Use it for fixed-price projects.Task

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions