Introduction
Real-time communication (RTC) is at the heart of Meta's services—from Messenger and Instagram video calls to low-latency Cloud Gaming and immersive VR casting on Meta Quest. To meet the performance demands of billions of users, Meta spent years developing a specialized, high-performance variant of the open-source WebRTC library. However, permanently forking a large open-source project often leads to a common industry pitfall: the forking trap. This article reveals how Meta escaped that trap by building a dual-stack architecture that enabled safe A/B testing across over 50 use cases, while keeping continuous upgrades with upstream WebRTC.

The Forking Trap
The forking trap begins with good intentions: you need a quick internal optimization or a specific bug fix. But over time, as the upstream project evolves and your internal features accumulate, the resources needed to merge external commits become prohibitive. Divergence grows, and the fork cuts itself off from community upgrades, security patches, and performance improvements. This is exactly what Meta faced with its WebRTC fork.
The Challenge: A Monorepo and a Static Linker
Upgrading a library like WebRTC is risky when serving billions of users. A one-time upgrade could introduce regressions across a vast diversity of devices and environments. Rollbacks are difficult. To mitigate this, Meta prioritized A/B testing capabilities: running the legacy fork alongside the new upstream version in the same app, with the ability to dynamically switch users between them. This would verify the new version without risking widespread disruption.
Static Linking and the One Definition Rule
Due to application build graph and size constraints, Meta sought a solution to statically link two versions of WebRTC. However, this violates the C++ linker's One Definition Rule (ODR), causing thousands of symbol collisions. The challenge was to make two versions of the same library coexist in the same address space within Meta's monorepo environment.
The Solution: Dual-Stack Architecture
Meta engineered a novel solution: a modular architecture built on top of the latest upstream WebRTC version, using it as a skeleton while injecting proprietary implementations of key components. This allowed building two versions of WebRTC simultaneously within a single library—a legacy fork and an upgraded version—for seamless A/B testing.

Resolving Symbol Collisions
To avoid ODR violations, Meta used techniques like namespace isolation and different linking orders, effectively hiding the internal symbols of one version from the other. This dual-stack approach meant both versions could coexist without linker conflicts.
A/B Testing Workflow
With the dual-stack in place, Meta implemented a dynamic switching mechanism. Each new upstream release is first tested on a small user segment before a full rollout. This continuous upgrade cycle ensures that Meta stays current with upstream, gaining performance improvements, binary size reductions, and security fixes—all while avoiding regressions.
Benefits and Results
- Performance: The modular design allowed selective upgrades of components, leading to better latency and throughput.
- Binary Size: By stripping unused parts of the old fork, Meta reduced the overall binary footprint.
- Security: Continuous integration with upstream means timely security patches.
- Scalability: The approach now supports over 50 use cases, from video calls to cloud gaming.
Conclusion
Meta's migration from a divergent WebRTC fork to a dual-stack, continuously upgraded architecture demonstrates a path out of the forking trap. By enabling safe A/B testing and maintaining upstream compatibility, Meta now enjoys the best of both worlds: tailored performance optimizations for its unique use cases, and the collective improvements of the open-source community. This approach is now a standard workflow for rolling out new WebRTC releases at Meta.