Scaling Excellence: How Grab Transformed Its Superapp Performance Through Advanced R8 Optimization

In the competitive landscape of Southeast Asian technology, Grab stands as a titan. As the region’s leading "superapp," it provides a singular ecosystem for mobility, food delivery, and financial services to millions of users across eight countries. However, with this massive scale comes a daunting engineering challenge: managing a decade-old codebase that has ballooned to over 10 million lines of code.
For years, the engineering team at Grab struggled with the "superapp tax"—the inevitable performance degradation that occurs as features are layered onto a monolithic architecture. The team faced a trifecta of technical hurdles: escalating Application Not Responding (ANR) rates that frustrated users, a ballooning app size that discouraged downloads, and a sluggish startup time that worsened with every annual update.
To combat this, the Passenger App Core team embarked on a multi-year engineering crusade to modernize their build pipeline. By leveraging R8 optimization, implementing Baseline Profiles, and enforcing strict CI/CD governance, the team achieved a staggering 32.5% reduction in ANRs, a 30% decrease in download size, and a 35% improvement in cold start times. This is the story of how Grab re-engineered its infrastructure to ensure that scale no longer comes at the cost of speed.
The Technical Crisis: A Decade of Technical Debt
By 2024, the Grab codebase had reached a critical mass. The reliance on a hybrid Bazel and Gradle build system—while robust—had become a bottleneck. The primary culprit for poor performance was the overhead of reading numerous DEX files during the app’s initialization phase.
Whenever a new version of the Grab app was released, users were greeted with "ANR spikes"—instances where the app would freeze or become unresponsive as the device struggled to process complex dependency graphs, such as Dagger, during the cold start. Relying on Google Play’s default Cloud Profiles was no longer sufficient, as Grab’s unique, high-traffic user journeys required highly specific initialization paths that standard cloud-based optimizations could not predict. The app was forced to rely on JIT (Just-In-Time) compilation and local background optimization, which left users experiencing poor performance for days after every update.

A Chronology of the Optimization Journey
Grab’s path to performance recovery was not a quick fix; it was a strategic, phased overhaul that spanned two years.
Phase 1: The R8 Optimization Rollout (2025)
The team initiated their recovery by moving away from legacy Proguard configurations. They adopted proguard-android-optimize.txt, effectively enabling R8 optimizations across the entire project. This was a high-stakes move given the age of the codebase, requiring the team to meticulously audit legacy configurations and resolve complex reflection usage that had been buried in the code for years.
Simultaneously, they implemented Baseline Profiles and Startup Profiles. Baseline Profiles allowed the team to specify critical user journey code paths, which Google Play then pre-compiled into machine code during installation. This removed the "JIT-lag" that previously crippled launch times. The results were immediate: a 25% reduction in user-perceived ANRs and a 16% reduction in download size.
Phase 2: The Full Mode Migration (2026)
Nine months later, the team pushed into "R8 Full Mode." This was the most challenging phase of the project. R8 Full Mode performs more aggressive optimizations, but it is notoriously unforgiving with reflection-heavy code.
To ensure stability, the team had to address how the app handled Java dynamic proxies and JSON parsing. By adopting the latest consumer keep rules from the Gson library and isolating specific reflection-dependent classes, they managed to enable Full Mode without destabilizing the app. This phase unlocked the next tier of performance, shaving off an additional 14% of the app’s download size and improving startup time by another 10%.

Phase 3: Keep-Rule Refinement and Governance
The final phase was not about writing new code, but about "hygiene." The team implemented the R8 Configuration Analyzer to systematically audit keep rules. By identifying and trimming unnecessary rules that were preventing R8 from shrinking the code, they achieved a final 3.6% reduction in app size. This phase established the culture of "compilation governance" that continues to protect the app’s performance today.
Supporting Data: The Impact at Scale
The cumulative impact of these changes is a testament to the power of build-time optimization. Below is a breakdown of the performance gains realized by the Passenger App Core team:
| Optimization Phase | ANR Reduction | Size Reduction | Cold Start Improvement |
|---|---|---|---|
| Phase 1: R8 Optimizer | ~25% | 16% | ~27% |
| Phase 2: R8 Full Mode | 10% | 14% | 10% |
| Keep-Rule Refinement | N/A | 3.6% | N/A |
| Cumulative Total | ~32.5% | ~30.4% | ~35% |
These figures represent a significant victory for the engineering department. By reducing the "code tax"—the relationship between lines of code and final APK size—Grab has ensured that their app will remain performant even as they continue to add features.
Official Perspectives: Why This Matters
Nguyen Van Minh, Lead Software Engineer on Grab’s Passenger App Core team, highlighted the recurring nature of the problem prior to the fix. "We consistently experienced ANR rate spikes with every weekly app release," he noted. The transition to a profile-guided optimization strategy was not just a technical upgrade; it was a shift in development philosophy.
The use of the app-sizer tool allowed the team to gain visibility into the cost of every feature. This data-driven approach changed the conversation between product managers and engineers. Instead of simply pushing for more features, the team could now quantify the "size cost" of a new module, forcing a more disciplined approach to architectural growth.

Implications: The Future of Superapp Development
The success of Grab’s optimization project holds significant implications for the wider mobile development community:
1. The Death of "Bloat"
In an era where AI-assisted coding is leading to an explosion in code volume, Grab’s model proves that developers do not have to accept "app bloat" as an inevitability. By using R8 to permanently lower the footprint of every line of code, Grab has demonstrated how to scale a codebase without scaling the app’s download size proportionally.
2. CI/CD Guardrails
The most significant long-term change is the implementation of automated pre-merge guardrails. By integrating R8 optimization scores into the CI/CD pipeline, Grab has created a system where performance regressions are caught before they ever reach the user. This "shift-left" approach to performance is becoming the new gold standard for high-traffic applications.
3. Sustainability of the Superapp Model
For the "superapp" business model to be sustainable, the user experience must remain fluid. If an app becomes too large or slow, users churn. By prioritizing build-time performance, Grab has protected the longevity of its platform. They have proven that with the right investment in build tooling and a rigorous approach to dependency management, a 10-million-line codebase can be as fast and responsive as a small, focused utility application.
Conclusion
Grab’s journey serves as a blueprint for any organization struggling with the technical debt of a maturing product. The transition from legacy Proguard to a sophisticated R8 Full Mode pipeline, supported by Baseline Profiles and strict keep-rule governance, has not only solved the immediate problem of ANRs and startup lag—it has fundamentally changed how Grab builds software. As they look toward the future, the team is well-positioned to maintain this high-performance standard, ensuring that the next 10 million lines of code are just as efficient as the first.
