πŸ“ WebRTC.rs Blog

Latest Posts

Announcing webrtc and rtc v0.21.0: The 1.0 Release Candidate

September 19, 2026

Treat v0.21.0 as 1.0.0-rc.1: the next release is 1.0.0, and until then the public API of webrtc and rtc stays stable unless a significant bug forces a change. The three items that had to land before 1.0 were done within four days: ULPFEC left the default codecs, the API was made extensible with #[non_exhaustive] and sealed traits, and crypto was unified behind a pluggable RTCCryptoProvider. Most of the optional work then landed too, and several pieces changed the public API: congestion control with a GCC estimator and pacer, transport objects, FlexFEC, and a jitter buffer. So we inserted one more release to test them before the freeze. The post checks every item from The Path to 1.0 against what shipped and covers the work that wasn't planned: the core now takes the time from its caller, slow consumers no longer drop data-channel messages, and several Chrome interop bugs are fixed. It also lists what didn't make it: browser interop in CI, continuous fuzzing, and a refreshed compliance table.

Read more β†’

The Interceptor Chain Is a List, Not a Tower

September 1, 2026

rtc 0.21 takes the interceptors that ship with the stack from six to thirteen β€” congestion control with a full GCC estimator, a pacer, FlexFEC both ways, a jitter buffer, RFC 8888 feedback, interval PLI β€” and rewrites the chain that holds them. Those are the same fact. The new interceptors are bidirectional, they have to see every byte that leaves including packets other interceptors generate, and they have to tell each other things across directions β€” and a tower of A<B<C>> fails all three, because nesting encodes one static containment relationship and none of those is one. So direction became a property of the walk (one list, ordered by distance from the wire, traversed forward to read and backward to write) and packets grew AttributedPacket to carry what the chain has learned. The worked example is congestion control: TWCC and RFC 8888 feedback flatten into one report shape, and the estimate reaches the pacer by riding an inbound packet β€” the only walk it can cross on. Also: why RTCPeerConnection is no longer generic, why slots go up by a thousand, and what the vtable dispatch costs.

Read more β†’

Bring Your Own Crypto Provider

September 1, 2026

rtc 0.21 routes every cryptographic operation through one provider-neutral crate. No protocol crate depends on ring, aws-lc-rs, or a RustCrypto primitive any more: RTCCryptoProvider bundles an operations trait and a CSPRNG, and it is an ordinary value you pass through configuration β€” so two peer connections in one process can use different providers, and an application can supply its own for OpenSSL, a FIPS module, or an HSM. The post covers the seven design principles behind the boundary (a provider is a value, not a global; factories rather than one-shot calls; primitives, not policy), how they landed across the workspace, and the three performance bugs the benchmarks found β€” none of which was the vtable dispatch everybody worries about.

Read more β†’

The Path to webrtc 1.0

August 1, 2026

webrtc 0.20.0 was out yesterday. Treat 0.20.0 as a 1.0.0-alpha.1 The API rough edges we knew about are fixed β€” the runtime seam, the interceptor type leak, the callback lifetimes β€” and what is left is validation. That is the position we are taking on the number itself: 1.0 is a commitment to API stability, not a claim of feature completeness. After the freeze we can add to the API, but we cannot fix it until the next major release β€” so this is the window in which feedback still changes anything.

Read more β†’

Announcing webrtc v0.20.0: Async-Friendly, Runtime-Agnostic WebRTC on Sans-I/O Core rtc πŸŽ‰

July 31, 2026

webrtc v0.20.0 is the first stable release of the new architecture, superseding the Tokio-coupled v0.17.x line. Highlights: a genuinely pluggable Runtime trait β€” runtime-neutral primitives, additive features, per-connection with_runtime, a deterministic MockRuntime. The post is also an audit of the January roadmap β€” what we achieved and what we did not. Delivered: the Quinn-style runtime abstraction, the push-based handler trait, deterministic Sans-I/O tests, and throughput past the target (689 Mbps single-connection, multi-Gbps aggregate, at ~a quarter of Pion's CPU cycles per byte). Not delivered: no stream layer, &self rather than &mut self on the handler, embassy still out of reach behind no_std, and a browser matrix with one automated cell β€” while async-std, one of the four runtimes the roadmap named, has since been discontinued. Closes with a migration path for v0.17.x adopters β€” callback hell, Arc explosion, leaked closures, and Tokio lock-in are all fixed on the other side of the port.

Read more β†’

Bring Your Own Async Runtime: Closing the Seam in webrtc's Runtime Abstraction

July 30, 2026

The webrtc crate advertised runtime independence, but the abstraction had a seam running through the middle of it: task spawning and sockets were injected as a value, while timers, channels, mutexes and notifications were resolved by fourteen #[cfg]-gated type aliases naming tokio::* or smol::* concretely. A custom runtime would have had its spawn used and its timers ignored β€” and because Cargo features are additive, a SmolRuntime could end up handed tokio timers that panic outside a tokio reactor, reachable by dependency-graph accident alone.

How a single question β€” does this touch the reactor? β€” resolved the whole design: inject what is reactor-bound, keep executor-agnostic primitives off the trait (which is what preserves object safety and avoids a viral <R: Runtime> parameter), and derive the rest. Covers the 8-method trait, why the settable process-global was cut, the deterministic MockRuntime, the poll-based socket path, and the three defects that only surfaced once someone actually tried to implement a runtime from outside the crate.

Read more β†’

Type-Erase the Interceptor Chain, Not Your Application: RTCPeerConnection<BoxedInterceptor>

July 28, 2026

Composing behaviour by wrapping β€” each layer generic over the next β€” is one of Rust's best zero-cost patterns, and one of the easiest ways to push a type into your users' data structures that they never chose and cannot name. rtc's interceptor chain was exactly that, until now: a struct holding a peer connection can finally be written RTCPeerConnection<BoxedInterceptor>, whatever chain it was built with.

A general look at the problem: why impl Trait postpones it by exactly one layer, and the two places you can erase the type. Erasing the holder behind a facade is right when the facade is the product β€” it is how the async webrtc crate is built over the Sans-I/O rtc core β€” and a costly workaround when it is only a mirror, flattening borrowing APIs into cloning ones. Erasing the parameter needs a dyn-compatible trait: the Sized supertrait that vetoes it, and the Box<P> impl that makes erasure a drop-in. Worked through with rtc's new BoxedInterceptor, and closing with what it did for the sfu crate.

Read more β†’

AppRTC Goes Group: Automatic P2P β†’ SFU Upgrade at appr.tc

July 22, 2026

appr.tc now speaks the full story: a 1:1 call stays direct peer-to-peer, and the moment a third browser joins the room, it upgrades itself to a Selective Forwarding Unit β€” mid-session, with no page reload, no second permission prompt, and no dropped frame. This post walks through the new V2 P2P/SFU signaling server: three cooperating processes behind one Sans-I/O authority (Collider β†’ RoomTable β†’ Room β†’ Client), the race-free upgrade barrier and signal epochs, perfect negotiation at the SFU boundary, and the one-app/two-layout browser that swaps a full-screen remote for a responsive grid.

Read more β†’

From 13 Mbps to Beating Pion: How We Made webrtc-rs Data Channels Fast (with AI on a Short Leash)

July 18, 2026 Β· Guest post by Stefano Di Martino (StefanoD)

When issue #101 was opened, webrtc-rs data channels ran at ~13 Mbps where Pion ran at ~570 Mbpsβ€” a 44Γ— gap. Eighteen PRs later, that gap is not just closed but reversed: webrtc-rs now beats Pion by roughly 2–3Γ— in multi-connection aggregate throughput, while burning 50–75% fewer CPU cycles, instructions, and cache misses per byte.

In this guest post, Stefano tells both stories at once: the optimizations themselves β€” scheduler wake coalescing, batch-draining the receive path, zero-copy hot paths, an O(rwnd)β†’O(streams) FORWARD-TSN rewrite, bounded memory, and adaptive UDP GSO β€” and the workflow that produced them: an AI coding agent kept honest by a harness of poop A/B runs, perf/bpftrace attribution, and a strict "never quote the RFC from memory" rule.

Read more β†’

Announcing sfu v0.20.0-rc.3: A Sans-I/O Selective Forwarding Unit in Rust

July 13, 2026

Meet a new member of the WebRTC.rs family: sfu, a Selective Forwarding Unit built on the Sans-I/O rtc core. The library crate has no sockets, no threads, and no clock of its own β€” it is a pure state machine, and the caller owns all I/O. Inside: three nested Sans-I/O layers (Sfu β†’ Room β†’ Client), ICE-lite ufrag demuxing over one shared socket, RTP fan-out with per-hop payload-type translation, RTCP keyframe relay, a live demo at sfu.rs, and the roadmap toward simulcast, pub/sub, TWCC, and AppRTC-based P2P + SFU signaling.

Read more β†’

WebRTC v0.20.0-rc.1: Toward Stable Async-Friendly webrtc Built on Sans-I/O rtc

June 30, 2026

We're excited to announce webrtc v0.20.0-rc.1, bringing the async webrtc crate to feature parity with the Sans-I/O rtc core. This release adds mDNS, TURN relay, ICE TCP, stronger socket error handling, broad async example parity, and AppRTC-backed browser interop testing support.

Read more β†’

WebRTC v0.20.0-alpha.1: Async-Friendly webrtc Built on Sans-I/O rtc

March 1, 2026

We're excited to announce the first pre-release of webrtc v0.20.0-alpha.1 β€” a ground-up rewrite of the async webrtc crate built on top of the Sans-I/O rtc protocol core. This milestone delivers runtime-agnostic support (Tokio and smol), full async API parity with the Sans-I/O rtc crate, a clean trait-based event handler replacing the old callback hell, and 20 working examples ported from v0.17.x.

Read more β†’

Building Async-Friendly webrtc on Sans-I/O rtc: Architecture Design and Roadmap

January 31, 2026

The webrtc-rs project is embarking on a significant architectural evolution. With webrtc v0.17.0 marking the final feature release of the Tokio-coupled implementation, we're now designing the next generation: an async-friendly API built on top of our Sans-I/O rtc crate, supporting multiple async runtimes while maintaining clean, ergonomic APIs.

Read more β†’

webrtc v0.17.0: Feature Freeze and Shifting to Build Async-Friendly API on Sans-I/O rtc Crate

January 31, 2026

webrtc v0.17.0 marks the final feature release of the Tokio-coupled async WebRTC implementation. This isn't an endingβ€”it's a strategic evolution toward a more sustainable, flexible, and robust architecture built on Sans-I/O rtc.

We discuss the critical issues driving this shift, including systematic memory leaks (~109 KiB per connection), tight Tokio coupling, and protocol/I/O entanglement. The new architecture provides runtime independence, proper resource management, and superior testing capabilities.

Read more β†’

WebRTC API Compliance: Sans-I/O rtc vs W3C Spec

January 24, 2026

How does a Sans-I/O WebRTC implementation in Rust compare to the browser-based W3C WebRTC API? We conducted a comprehensive compliance analysis and found 95%+ compliance despite fundamental architectural differences. Explore how rtc achieves W3C-compliant WebRTC implementation while maintaining the determinism and testability of sans-I/O architecture.

For the complete interface-by-interface comparison, see the Full WebRTC API Compliance Analysis.

Read more β†’

Perfect Negotiation in WebRTC: A Deep Dive into rtc Implementation

January 23, 2026

Perfect Negotiation is a modern WebRTC pattern that eliminates asymmetry in peer-to-peer connections. This comprehensive deep dive explores the pattern from first principles, examines the rtc implementation, and walks through a complete working example.

Learn how to handle bidirectional calling, collision detection, and rollback mechanics with Sans-I/O WebRTC.

Read more β†’

RTC Feature Complete: What's Next for Sans-I/O WebRTC

January 18, 2026

With the release of rtc 0.8.0, the sans-I/O WebRTC implementation has reached a significant milestone: full feature parity with the async-based webrtc crate and comprehensive W3C WebRTC API compliance.

This article reflects on what we've achieved and outlines the roadmap for what comes next, focusing on four key areas: browser interoperability, performance engineering, test coverage, and code quality.

Read more β†’

Stats Collector Design: An Incremental Accumulation Approach

January 17, 2026

WebRTC statistics are essential for monitoring connection health, debugging issues, and implementing adaptive quality control. This article examines how RTC collects W3C-compliant statistics without async runtimes, background tasks, or locks.

Using an incremental accumulation pattern, stats are updated as packets flow through the handler pipeline, then snapshots are taken instantly on demand via get_stats(). The design achieves zero-cost collection, instant snapshots, and deterministic testing with explicit timestamp parameters.

Read more β†’

Announcing rtc 0.8.0: WebRTC Stats Collection for Sans-I/O πŸ“Š

January 17, 2026

We're thrilled to announce rtc 0.8.0, a major milestone that brings comprehensive WebRTC statistics collection to our sans-I/O WebRTC implementation.

This release implements the W3C WebRTC Stats API, enabling applications to monitor and diagnose peer connection health, media quality, and network performanceβ€”all without sacrificing the zero-overhead design principles of sansio. Features include instant synchronous snapshots, zero-cost accumulation, and the W3C stats selection algorithm with StatsSelector.

Read more β†’

Announcing rtc 0.7.0: mDNS Support for Privacy-Preserving WebRTC πŸŽ‰

January 10, 2026

We're excited to announce rtc 0.7.0, a significant release that brings multicast DNS (mDNS) support to our sans-I/O WebRTC implementation.

This release enables privacy-preserving peer connections by hiding local IP addresses with .local hostnames, following RFC 6762 and WebRTC best practices. The mDNS implementation spans three layers: a new rtc-mdns crate, seamless ICE agent integration, and user-friendly configuration APIs.

Read more β†’

Interceptor Design Principle: Composable RTP/RTCP Processing with sansio::Protocol

January 9, 2026

Interceptors sit between the SRTP layer and the application endpoint, processing RTP and RTCP packets to implement features like NACK, RTX, TWCC, and RTCP reports.

This article explains the re-design of the interceptor framework using the sansio::Protocol trait and generic composition instead of async trait objects, achieving zero-cost abstraction and runtime independence.

Read more β†’

Announcing rtc 0.6.0: Interceptor Framework Complete 🎊

January 9, 2026

We're thrilled to announce rtc 0.6.0, a major milestone release that completes the Interceptor framework for our sans-I/O WebRTC implementation.

This release achieves interceptor feature parity with the async-based webrtc crate, bringing RTCP feedback mechanisms for adaptive streaming, packet loss recovery, and congestion control. The simulcast example now achieves highest quality streaming from browsers thanks to proper RTCP feedback!

Read more β†’

Announcing rtc 0.5.0: Enhanced Simulcast Support and API Refinements πŸš€

January 5, 2026

We're excited to announce rtc 0.5.0, bringing comprehensive simulcast support and significant API improvements to our sans-I/O WebRTC stack.

This release introduces first-class support for multiple RTP encodings per track, enabling advanced features like simulcast and SVC. The API has been refined to better represent WebRTC's multi-encoding model, making it easier to work with modern video streaming scenarios.

Read more β†’

Building WebRTC's Pipeline with sansio::Protocol: A Transport-Agnostic Approach

January 4, 2026

WebRTC is not a single protocol but a stack of tightly interrelated protocols: ICE for connectivity, DTLS for security, SCTP for reliable data channels, and SRTP for media transport.

This article explores building WebRTC as a pure protocol pipeline using the sans-I/O pattern. By separating protocol logic from all I/O concerns, we can model WebRTC as a sequence of composable handlers, each acting as a deterministic state machine.

Read more β†’

Announcing rtc 0.3.0: Sans-I/O WebRTC Stack for Rust πŸŽ‰

January 4, 2026

We're excited to announce the first public release of rtc, a pure Rust WebRTC implementation built on a sans-I/O architecture.

Sans-I/O (without I/O) is a design pattern where the library handles all protocol logic, but you control the I/O operations. This architecture provides runtime independence, full control over threading and scheduling, better testability, and flexible integration options.

Read more β†’

← Back to Home