πŸ“ WebRTC.rs Blog

Latest Posts

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