Southeast Asia’s leading superapp, Grab, has achieved a major technological milestone by dramatically improving the performance, responsiveness, and efficiency of its massive Android application. Operating across eight countries and serving millions of daily active users, the platform integrates an extensive array of services—including food and package deliveries, urban mobility, and financial services—into a single, unified mobile application. However, managing this vast ecosystem brought severe technical friction over time. Operating on a decade-old codebase comprising more than 10 million lines of code and hundreds of third-party libraries built on a hybrid Bazel and Gradle setup, the Grab engineering team confronted a triad of growing engineering bottlenecks: soaring Application Not Responding (ANR) rates, a continuously expanding app download size driven by the addition of new services, and a slow, creeping degradation of app startup times year over year.

To reverse these trends, the Grab Passenger App Core team executed a comprehensive architectural optimization campaign. By systematically enabling R8 code optimization, refining keep rules, and introducing Baseline Profiles and Startup Profiles, the company achieved remarkable results. The optimization efforts reduced user-perceived ANR rates by roughly 32.5 percent, cut the application download size by approximately 30.4 percent, and accelerated cold startup times by about 35 percent. These technical enhancements not only delivered a smoother and more reliable user experience across diverse mobile hardware markets in Southeast Asia but also established a sustainable framework for future codebase scalability.

Eliminating Post-Release ANR Spikes for a Smoother User Experience

Prior to undertaking this deep performance overhaul, Grab routinely battled cold start delays and sharp spikes in Application Not Responding errors immediately following new application updates. These performance regressions were primarily driven by the heavy I/O overhead of reading numerous DEX files during the app initialization phase. While Google Play’s Cloud Profiles offered generalized optimization for standard user flows across the broader Android ecosystem, they fell short of covering all the specialized initialization paths required for Grab’s complex core user journeys. Essential operations, such as instantiating intricate Dagger dependency graphs during app launch, often remained unoptimized in the initial distribution package, forcing client devices to rely on Just-In-Time (JIT) compilation and local background optimizations over the course of several days.

To bridge this gap, the engineering team implemented custom Baseline Profiles and Startup Profiles, effectively integrating critical user journeys directly into Google Play’s Cloud Profiles. This strategic shift ensured that vital execution paths were compiled directly into native machine code immediately upon installation rather than waiting for background processing.

Grab Reduces ANRs by 32% and improves startup time by 35% with R8 and Profile guided optimization | Android Developers' Blog

Nguyen Van Minh, Lead Software Engineer on Grab’s Passenger App Core team, noted the persistence of the issue prior to the intervention, explaining that the platform consistently experienced ANR rate spikes with every weekly application release.

By pairing profile-guided optimization with the R8 code optimizer, the team achieved an immediate 12 percent cold start improvement from R8 alone, supplemented by an additional 15 percent boost from Baseline Profiles. Together, these measures yielded a 27 percent faster startup time and effectively neutralized the recurring post-release ANR spikes. The execution of this optimization strategy unfolded across three distinct phases: initial adoption of R8 optimization in compatibility mode, a subsequent migration to R8 Full Mode, and rigorous keep-rule refinement paired with continuous CI/CD governance.

Phase 1: Enabling R8 Optimization and Initial Migrations

The optimization journey began with moving away from the legacy default Proguard configuration in favor of proguard-android-optimize.txt, which unlocks the powerful optimization capabilities of the R8 compiler. Given that Grab’s codebase spans ten years of continuous feature development and exceeds 10 million lines of code, turning on the optimizer presented immediate hurdles related to legacy configurations and widespread reflection usage.

To maximize the impact of this foundational phase, the team coordinated the rollout of R8 in compatibility mode alongside the deployment of Baseline Profiles and Startup Profiles. This synchronized effort produced an immediate 25 percent reduction in user-perceived ANR rates, a 16 percent decrease in app download size, and a 27 percent improvement in cold start speeds.

Grab Reduces ANRs by 32% and improves startup time by 35% with R8 and Profile guided optimization | Android Developers' Blog

Phase 2: R8 Full Mode Migration and Resolving Reflection Challenges

Building upon the initial success of compatibility mode, the engineering team advanced to R8 Full Mode approximately nine months later to unlock deeper code shrinking and optimization passes. While standard third-party libraries like Retrofit, Firebase, and Jetpack Compose integrated smoothly using their built-in consumer rules, migrating the remainder of the massive enterprise codebase required carefully isolating and resolving reflection-heavy code paths.

To achieve a clean migration, the team adopted updated consumer keep rules from modern Gson releases to guarantee flawless JSON parsing behavior. Furthermore, they tackled compilation challenges associated with Java dynamic proxies, which utilize runtime reflection to generate interface implementations dynamically. Because the R8 compiler cannot statically detect runtime usage during the build phase, it risks stripping or renaming necessary classes, leading to application crashes. Rather than applying overly broad exceptions that would inadvertently bloat the application package, Grab’s engineers isolated the specific classes relying on reflection and implemented highly targeted keep rules. This precision approach preserved application stability while retaining maximum optimization efficiency.

The transition to R8 Full Mode delivered compounding architectural benefits, including an additional 14 percent reduction in app download size, an extra 10 percent improvement in startup velocity, and a further 10 percent decrease in user-perceived ANRs. These performance milestones allowed the codebase to achieve high optimization scores, providing objective metrics on configuration health and highlighting areas requiring further rule refinement.

Phase 3: Keep-Rule Refinement and Automated Governance

In the final phase of the optimization initiative, Grab shifted its focus toward long-term codebase hygiene, continuous performance tracking, and strict compilation governance. To systematically measure rule effectiveness and prevent configuration regressions across ongoing weekly release cycles, the engineering group integrated the R8 Configuration Analyzer directly into their evaluation workflow. This diagnostic tool provides deep visibility into how effectively the application’s keep rules permit R8 to optimize, shrink, and obfuscate the binary.

Grab Reduces ANRs by 32% and improves startup time by 35% with R8 and Profile guided optimization | Android Developers' Blog

Methodically trimming legacy keep rules yielded an additional 3.6 percent reduction in app download size. More importantly, tracking these diagnostic metrics provided the engineering organization with the empirical data needed to establish automated pre-merge guardrails within their continuous integration pipeline. These guardrails ensure that newly introduced code adheres strictly to keep-rule standards, protecting hard-won performance gains against future regressions.

Beyond immediate performance figures, the adoption of R8 introduced a permanent structural advantage for Grab’s massive repository. Using an open-source measurement tool known as app-sizer, the team observed that R8 permanently lowered the marginal download-size cost of every new line of code added to the application. In an era shaped by AI-assisted software development, where code volume can expand at unprecedented rates, this structural efficiency is vital. Without R8, rapid code expansion translates directly into a bloated application footprint; with R8 enabled, the platform maintains a heavily optimized memory and storage footprint despite continuous feature growth.

To safeguard these achievements over the long term, Grab continues to enforce automated CI policies where new keep rules are strictly restricted and subjected to mandatory engineering review. By combining automated feedback loops with proactive governance, Grab has ensured that its superapp remains fast, responsive, and lean, delivering a reliable digital experience to millions of users across Southeast Asia.

Leave a Reply

Your email address will not be published. Required fields are marked *