[KotlinConf2024] Kotlin Multiplatform Powers Google Workspace
At KotlinConf2024, Jason Parachoniak, a Google Workspace engineer, detailed Google’s shift from a Java-based multiplatform system to Kotlin Multiplatform (KMP), starting with Google Docs. For over a decade, Workspace has relied on shared code for consistency across platforms, like Gmail’s synchronization layer. Jason shared how KMP enhances this approach, leveraging Kotlin’s ecosystem for better performance and native interop. The talk highlighted lessons from the migration, focusing on build efficiency, runtime latency, and memory challenges, offering insights for large-scale KMP adoption.
Why Kotlin Multiplatform for Workspace
Google Workspace has long used multiplatform code to ensure consistency, such as identical email drafts across devices in Gmail or uniform document models in Docs. Jason explained that their Java-based system, using transpilers like J2ObjC, was effective but complex. KMP offers a modern alternative, allowing developers to write Kotlin code that compiles to native platforms, improving runtime performance and ecosystem integration. By targeting business logic—everything beyond the UI—Workspace ensures native-feel apps while sharing critical functionality, aligning with user expectations for productivity tools.
Google Docs: The Migration Testbed
The migration began with Google Docs, chosen for its heavily annotated codebase, which tracks build performance, latency, and memory usage. Jason described how Docs is rolling out on KMP, providing metrics to refine the Kotlin compiler and runtime. This controlled environment allowed Google to compare KMP against their legacy system, ensuring parity before expanding to other apps. Collaboration with JetBrains and the Android team has been key, with iterative improvements driven by real-world data, setting a foundation for broader Workspace adoption.
Tackling Build Performance
Build performance posed challenges, as Google’s Bazel-like system resembles clean builds, unlike Gradle’s incremental approach. Jason recounted a 10-minute build time increase after a Kotlin Native update optimized LLVM bitcode generation. While this improved binary size and speed, it slowed builds. Profiling revealed a slow LLVM pass, already fixed in a newer version. Google patched LLVM temporarily, reducing build times from 30 to 8 minutes, and is working with JetBrains to update Kotlin Native’s LLVM, prioritizing stability alongside the K2 compiler rollout.
Optimizing Runtime Latency
Runtime latency, critical for Workspace apps, required Kotlin Native garbage collection (GC) tweaks. Jason noted that JetBrains proactively adjusted GC before receiving Google’s metrics, but further heuristics were needed as latency issues emerged. String handling in the interop layer also caused bottlenecks, addressed with temporary workarounds. Google is designing long-term fixes with JetBrains, ensuring smooth performance across platforms. These efforts highlight KMP’s potential for high-performance apps, provided runtime challenges are systematically resolved through collaboration.
Addressing Memory Usage
Memory usage spikes were a surprise, particularly between iOS 15 and 16. Jason explained that iOS 16’s security-driven constant pool remapping marked Kotlin Native’s vtables as dirty, consuming megabytes of RAM. Google developed a heap dump tool generating HPROF files, compatible with IntelliJ’s Java heap analysis, to diagnose issues. This tool is being upstreamed to Kotlin Native’s runtime, enhancing debugging capabilities. These insights are guiding Google’s memory optimization strategy, ensuring KMP meets Workspace’s stringent performance requirements as the migration expands.