Southeast Asia’s leading superapp, Grab, has achieved a massive architectural turnaround, successfully reducing user-perceived App Not Responding (ANR) rates by roughly 32.5 percent, cutting its app download size by more than 30 percent, and accelerating cold startup times by 35 percent. Operating across eight countries with an expansive ecosystem spanning deliveries, mobility, and financial services, the company faced mounting technical debt within a ten-year-old codebase containing over 10 million lines of code and hundreds of third-party libraries built on a hybrid Bazel and Gradle setup.

For years, the sheer scale of the application introduced compounding performance hurdles. As the superapp continuously added new services to its single-app interface, the application package grew increasingly bloated. Startup times crept upward year over year, and users frequently encountered frustrating performance spikes immediately following new app updates. Behind these post-release slowdowns was the heavy overhead of reading numerous DEX files during initial app loading sequences.

To confront these scaling issues head-on, the engineering team at Grab embarked on a multi-phase optimization initiative. By leveraging advanced compiler features, refining application configuration rules, and integrating modern performance profiling tools, the company managed to drastically improve runtime efficiency while establishing long-term architectural health across its massive mobile ecosystem.

Eliminating Post-Release ANR Spikes for a Smoother User Experience

Prior to undertaking its systematic build optimization, Grab struggled with consistent cold start delays and abrupt ANR spikes following every weekly release cycle. While standard mechanisms like Google Play’s Cloud Profiles offered general optimizations for baseline user flows across the broad user base, they fell short of covering all the complex initialization paths required for Grab’s critical user journeys. Essential operations, such as initializing Dagger dependency graphs during app launch, often fell outside the scope of initial distribution packages. Consequently, devices were forced to rely on Just-In-Time (JIT) compilation and local background optimizations over the course of several days following an installation.

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

To bridge this gap, the engineering team implemented custom Baseline Profiles and Startup Profiles. Profile-guided optimization, working in tandem with advanced compiler configurations, delivered immediate performance dividends. Nguyen Van Minh, Lead Software Engineer on Grab’s Passenger App Core team, noted that the application had historically experienced persistent ANR spikes with every single weekly deployment. By introducing targeted profiles, critical user journeys were compiled directly into machine code immediately upon installation, effectively eliminating post-release performance degradation and yielding a cumulative 35 percent improvement in cold start speeds.

The execution of this sweeping optimization strategy was divided into distinct operational phases, beginning with the adoption of optimized compiler configurations and culminating in rigorous continuous integration governance.

Phase 1: Enabling R8 Optimization

In the initial stage of the modernization effort, Grab transitioned away from legacy Proguard configurations and adopted default optimization rules that enabled the R8 compiler. Because the codebase had evolved over a decade and spanned more than 10 million lines of code, turning on the aggressive optimizer required careful navigation of legacy configurations and extensive reflection usage.

To maximize the impact of this foundational rollout, the team combined R8 compat mode with Baseline 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 an overall 27 percent boost 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

Building upon the initial success of compat mode, Grab advanced to R8 Full Mode approximately nine months later. This transition unlocked deeper, more aggressive optimizations across the entire project. While standard libraries like Retrofit, Firebase, and Jetpack Compose integrated smoothly using their built-in rules, migrating the remainder of the massive codebase required resolving complex, reflection-heavy code paths.

To achieve a seamless migration without breaking functionality, the team adopted consumer keep rules from modern Gson releases to ensure reliable JSON parsing. They also addressed runtime challenges associated with Java dynamic proxies, which use reflection to generate interface implementations dynamically. Because the compiler cannot detect runtime usage during compilation, it risks stripping or renaming essential classes, leading to application crashes. Rather than applying broad exceptions that would unnecessarily bloat the application package, engineers isolated the specific classes relying on reflection and implemented highly targeted keep rules.

These precise adjustments preserved both application stability and optimization efficiency. Ultimately, R8 Full Mode delivered compounding architectural improvements, generating an additional 14 percent reduction in app download size, a 10 percent improvement in startup velocity, and another 10 percent drop in user-perceived ANRs.

Keep-Rule Refinement and Long-Term Governance

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

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

By methodically trimming legacy keep rules and building on the foundation of R8 Full Mode, the team secured an additional 3.6 percent reduction in download size. More importantly, tracking these diagnostic metrics provided engineers with the objective data required to implement automated pre-merge checks within their continuous integration pipeline. These guardrails ensure that newly introduced code adheres to strict keep-rule standards, protecting hard-won performance gains against future bloat.

Ensuring Codebase Health in the Era of AI-Assisted Development

Beyond immediate runtime and storage metrics, enabling advanced compiler optimizations yielded a permanent structural advantage for Grab’s massive codebase. Using an open-source tool designated for measuring package composition, the team observed that R8 permanently lowered the marginal cost of every individual line of code in terms of download size.

In an era defined by rapid code generation and AI-assisted development, where code volume often expands at an unprecedented pace, this structural efficiency is increasingly critical. Without aggressive compilation and shrinking, code expansion leads to proportional increases in memory and storage footprints. The optimization pipeline ensures that even as the codebase continues to scale to meet business demands, the application maintains a significantly reduced resource footprint, delivering a faster, more stable superapp experience for millions of users across Southeast Asia.

Leave a Reply

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