Southeast Asia’s leading superapp, Grab, has achieved significant performance and efficiency milestones across its massive Android application. Operating in eight countries and serving millions of daily active users, Grab offers a unified platform encompassing ride-hailing, food delivery, logistics, and financial services. However, maintaining a decade-old codebase spanning more than 10 million lines of code and hundreds of third-party libraries under a hybrid Bazel and Gradle setup presented mounting engineering hurdles.

The engineering team faced a triad of compounding challenges: rising Application Not Responding (ANR) rates following new releases, an expanding app download size driven by continuous feature rollouts, and a cold start time that crept upward year over year. To address these bottlenecks, the Passenger App Core team embarked on a multi-phase optimization initiative. By implementing R8 code optimization, refining keep rules, and deploying Baseline Profiles alongside Startup Profiles, Grab slashed its user-perceived ANR rate by approximately 32.5 percent, reduced app download size by roughly 30.4 percent, and improved startup times by 35 percent.

Eliminating Post-Release ANR Spikes for a Smoother User Experience

Prior to overhauling its build and compilation processes, Grab wrestled with persistent cold start delays and sharp spikes in ANR rates immediately following weekly app updates. These performance regressions were primarily caused by the heavy overhead of reading numerous DEX files during the application’s initialization phase.

While Google Play’s Cloud Profiles offered baseline optimizations for standard user flows across the broader Android ecosystem, they fell short of covering all initialization paths unique to Grab’s critical user journeys. Specifically, standard cloud distribution overlooked vital initialization sequences required during app launch, such as building Dagger dependency graphs. For code paths omitted from the initial distribution, devices had to rely on Just-In-Time (JIT) compilation and local background optimization over the course of several days, leaving early users vulnerable to latency.

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

To close this gap, Grab integrated custom Baseline Profiles directly into Google Play’s distribution pipeline. This ensured that critical user journeys were compiled down to machine code immediately upon installation rather than waiting for background compilation. Coupled with the R8 optimizer, this profile-guided optimization yielded an immediate 12 percent cold start improvement from R8 and an additional 15 percent gain from Baseline Profiles. Together, these measures accelerated startup times by 27 percent and effectively eliminated the post-release ANR spikes that had troubled previous releases.

Phase 1: Enabling R8 Optimization

The optimization initiative rolled out in distinct strategic phases, beginning with the adoption of modern optimization configurations. In the first phase, shipped in 2025, Grab moved away from its legacy default Proguard setup and adopted proguard-android-optimize.txt. Because the codebase was over a decade old and contained more than 10 million lines of code, enabling the aggressive optimizer required careful navigation of legacy configurations and reflection patterns.

To maximize the impact of this foundational step, the team paired the R8 Compat mode enablement with customized Baseline Profiles and Startup Profiles. This combined effort resulted in an immediate 25 percent reduction in user-perceived ANR rates, a 16 percent reduction in app download size, and an overall 27 percent improvement in cold start performance.

Phase 2: R8 Full Mode Migration

Building on the success of Compat mode, Grab advanced to R8 Full Mode nine months later, unlocking deeper optimization potential across the application. While standard modern libraries such as Retrofit, Firebase, and Jetpack Compose operated smoothly under R8 using their built-in rules, migrating the remainder of the sprawling codebase required resolving complex reflection-heavy code paths.

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

To achieve a seamless transition to R8 Full Mode, the team adopted consumer keep rules from the latest Gson release to guarantee stable JSON parsing. They also tackled optimization hurdles associated with Java dynamic proxies, which leverage runtime reflection to generate interface implementations dynamically. Because R8 cannot detect these runtime patterns during compile time, it risks stripping or renaming essential classes, which would otherwise lead to application crashes. Rather than applying broad exceptions that would inadvertently bloat the application package, the team isolated the specific classes relying on reflection and implemented highly targeted keep rules to preserve stability without sacrificing optimization efficiency.

Ultimately, R8 Full Mode delivered compounding architectural improvements, yielding an additional 14 percent reduction in app download size, a 10 percent boost in startup speed, and a further 10 percent decrease in user-perceived ANRs.

Keep-Rule Refinement and Governance

In the final phase of the optimization roadmap, Grab shifted its focus toward long-term codebase health, continuous performance monitoring, and strict compilation governance. To systematically measure rule hygiene and prevent configuration regressions across ongoing development cycles, the engineering team integrated the R8 Configuration Analyzer into their evaluation workflow. This diagnostic tool provided deep visibility into how effectively Grab’s keep rules allowed R8 to optimize, shrink, and obfuscate the application.

By building on the foundation of R8 Full Mode and methodically trimming legacy keep rules, the team secured an additional 3.6 percent reduction in app download size. More importantly, tracking these diagnostic metrics provided engineers with objective data to establish automated pre-merge CI guardrails. These checks ensure that newly introduced code adheres to strict keep-rule standards and that hard-won performance gains remain protected over time.

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

Technical Challenges and Long-Term Code Impact

Deploying the R8 optimizer across a decade-old superapp codebase introduced notable technical hurdles at scale, primarily centered around managing legacy reflection, dynamic proxy generation, and maintaining strict keep rules without breaking runtime behavior. Overcoming these obstacles required methodical isolation of legacy components and close alignment with modern build standards.

Beyond immediate performance gains, the R8 rollout established a permanent structural advantage for Grab’s massive repository. Utilizing the open-source tool app-sizer, the engineering team measured the ongoing impact of R8 and discovered that the optimizer permanently lowered the download-size cost of every line of code in the application. In the era of AI-assisted software development, where code volume can expand rapidly, this structural efficiency is vital. Without R8, code expansion proportionally increases download size; with R8, the same rate of code growth maintains a drastically reduced memory footprint.

Grab’s comprehensive optimization journey successfully countered the mounting performance penalties of a maturing, large-scale codebase. By combining Baseline Profiles, Startup Profiles, and a systematic migration to R8 Full Mode, the team delivered a faster, more stable superapp experience while establishing rigorous automated guardrails to preserve these engineering achievements for millions of users across Southeast Asia.