Last year, we introduced the DAVE protocol as our solution to bring end-to-end encryption ("E2EE" for short) to Discord's audio and video calls. Since then, DAVE has been providing E2EE for tens of millions of calls on Discord every single day. Today, we're excited to announce that we're bringing DAVE support to all our remaining platforms, including browsers, consoles and our Social SDK.Starting March 1st 2026, clients and apps without DAVE support will no longer be able to participate in Discord calls. This will complete our transition from last year’s experimental rollout to making DAVE the standard for Discord voice and video calls.In this article, we'll explore the technical challenges and tradeoffs we encountered while integrating DAVE with web browsers, from WebAssembly performance considerations to Web Worker architecture decisions. We'll also share more about our timeline for deprecating non-E2EE calls and what you may need to do to make sure you or your application can still connect to voice channels come March 1st 2026.The Technical Challenges of Browser Support From the very beginning, we designed DAVE with web browsers in mind, ensuring it could support the same breadth of video codecs as our other platforms. Planning this from the outset would ensure a better video call experience, as modern devices deliver excellent hardware support for codecs like H.265 and AV1 giving users better video quality and more efficient bandwidth utilization.The Encoded Transform APIAs mentioned in our previous blog post, using the WebRTC Encoded Transform API was a crucial choice to support DAVE on web browsers.In essence, this API allows us to perform end-to-end encryption of audio and video data inside the WebRTC pipeline.While adding support for the WebRTC Encoded Transform API across browsers, we encountered an unexpected challenge with Firefox. The initial proof-of-concept worked well and DAVE’s encryption functioned as expected in controlled tests. However, when we tried using DAVE in real Discord calls, it stopped working. The Web Worker responsible for encryption wasn't receiving any data from the WebRTC Encoded Transforms API.After extensive debugging through our application stack didn’t resolve the issue, we decided to build Firefox from source to investigate at the browser level. That’s when we discovered a small edge case: the FrameTransformerProxy that is backing RTCRtpScriptTransform in Firefox could become deadlocked when video data was fed to the transformer too early. The video data was stored for deferred processing, which happens under a mutex accessed again by the transform operation causing a recursive deadlock.We were very impressed with Mozilla's responsiveness throughout this process. Building and navigating the Firefox codebase proved surprisingly straightforward, and the entire process - from downloading the repository to submitting our patch - took just over a day. Mozilla quickly responded to our submission, and after a few rounds of implementation tweaks, the patch was merged! These fixes are now available in Firefox v142.0, which will be the minimum version required to use DAVE on Firefox.Leveraging Web Workers for EncryptionEach Discord connection uses a dedicated Web Worker to handle encryption and decryption of media streams before handing it back to the web browser that will perform the encoding or decoding. For Discord calls, one worker handles encryption and decryption of the audio and camera video for the call, while separate workers handle the same for the stream’s audio and video for associated screenshare and game streams.Each WebRTC audio and video stream has a unique SSRC (Synchronization Source identifier) that is transmitted with every frame. With DAVE, we use this SSRC to identify which symmetric encryption key to use for each frame. Each Web Worker maintains only the necessary context about the call: incoming and outgoing audio and video data, a mapping of SSRCs to User IDs, and the encryption keys for each user. This design keeps the worker lightweight and focused solely on the cryptographic operations.The JavaScript main thread manages the WebRTC connection, tracking which users are in the call and their different media tracks. The main thread also handles the Messaging Layer Security (MLS) negotiation when users join or leave calls. This separation is crucial for performance, as MLS group changes can proceed immediately without requiring round-trip to the worker which may need to finish encrypting a frame first, thus minimizing latency during member joins and leaves.Whenever a change occurs to the MLS session, such as a user joining or leaving the call, the main thread sends a message to the worker to update its cryptographic state. This asynchronous approach ensures that encryption operations continue smoothly while group membership changes are processed.Reusing Proven Code with WebAssemblyOur DAVE implementation has been battle-tested across Discord's entire ecosystem, processing billions of encrypted calls on both desktop and mobile. By compiling this same C++ codebase to WebAssembly, we eliminate the risk of platform-specific bugs that could compromise security or performance. This isn't just about code reuse, it’s about deploying cryptographic logic that has already proven its reliability under the massive scale of Discord's daily usage.The encryption process requires careful considerations to leave the metadata required by the WebRTC packetizer unencrypted. Once the data leaves the encryptor, it cannot be modified in any way before it reaches the decryptor or the decryption will fail. For that to be possible, the encryptor needs to output data that will go through the WebRTC packetizer, Selective Forwarding Unit and WebRTC depacketizer untouched.This byte-level parsing and selective encryption is computationally intensive and error-prone to implement. WebAssembly gives us near-native performance for these operations while avoiding the complexity and potential bugs of reimplementing this logic in JavaScript.Performance Trade-offs: WebAssembly vs. SubtleCryptoWhile WebAssembly brings significant advantages for frame parsing, we do pay a minimal performance cost for cryptographic operations compared to native browser APIs like SubtleCrypto. However, our benchmarking revealed surprising nuances in these trade-offs:-----------------------------------------------------
Bringing DAVE to All Discord Platforms
From March 1st, 2026, all clients and apps must be updated to utilize DAVE’s end-to-end encryption support for voice and video calls. In this blog, we explore the challenges we encountered bringing E2EE to browsers, and share what you may need to do to ensure your app can still connect to voice calls in 2026.






