# Architecture of the Huddle Audio WebSocket Opus Relay in Buzz

> Explore the Huddle audio WebSocket Opus relay architecture in Buzz. Understand its three-layer design: WebSocket entry, audio room manager, and wire protocol for efficient real-time audio.

- Repository: [Block Open Source/buzz](https://github.com/block/buzz)
- Tags: architecture
- Published: 2026-08-29

---

**Buzz implements Huddle audio as a real-time Opus-only relay built on a three-layer architecture consisting of a WebSocket entry point, an audio room manager, and a wire protocol layer that handles parsing and broadcasting.**

The **Huddle audio WebSocket Opus relay** powers real-time voice communication in the Buzz decentralized social protocol. According to the block/buzz source code, the relay operates entirely on the **buzz-relay** server and forwards raw Opus payloads without transcoding, minimizing latency while enforcing strict protocol versioning and admission control.

## Three-Layer System Architecture

The relay consists of three tightly-coupled layers that handle connection establishment, state management, and frame distribution.

| Layer | Component | Key File |
|-------|-----------|----------|
| **WebSocket Entry Point** | Handles the `GET /huddle/:channel/audio` upgrade, NIP-42 authentication, and protocol version negotiation | [`crates/buzz-relay/src/handlers/huddle.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/handlers/huddle.rs) |
| **Audio Room Manager** | Maintains the `Room` state, peer indices, version pinning, and admission gates | [`crates/buzz-relay/src/audio/room.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/audio/room.rs) |
| **Wire Protocol** | Parses the 8-byte frame headers, clamps telemetry, and manages v2/v3 prefix formats | [`crates/buzz-relay/src/audio/wire.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/audio/wire.rs) |

When a client connects, the handler in [`huddle.rs`](https://github.com/block/buzz/blob/main/huddle.rs) upgrades the HTTP request to a binary WebSocket and forwards the stream to the audio subsystem, which creates or retrieves a `Room` instance via the `AudioRoomManager`.

## Admission Control and Version Pinning

The `Room::add_peer` routine enforces strict admission rules to ensure protocol consistency within a channel.

When the **first peer joins** a room, the system creates a **pinned_version** based on the client's advertised protocol version. All subsequent joins must present the exact same version, or the admission guard returns an `AdmissionError::VersionMismatch`. This pin persists across peer churn and is cleared only when `AudioRoomManager::cleanup_if_empty` destroys the empty room.

The admission sequence follows five sequential steps:

1. Acquire the `AdmissionGuard` mutex for exclusive access to the ended flag, peer count, and version pin
2. Reject if the room is **ended** or **full** (`MAX_PEERS_PER_ROOM = 25`)
3. Verify the requested protocol version matches the pinned version
4. Allocate a **peer_index** and **epoch** via `AdmissionGuard::alloc`, incrementing the epoch each time an index is reused
5. Insert the new `AudioPeer` into the `DashMap` and broadcast a `RosterDelta` to all connected clients

This design prevents version skew and allows receivers to fence stale frames using the epoch counter.

## Wire Protocol and Frame Parsing

Clients prepend an 8-byte **v2 header** (`V2_HEADER_LEN = 8`) to every Opus payload before transmission over the WebSocket.

```

Bytes 0-1 : seq (u16) - Sequence number
Bytes 2-5 : ts_48k (u32) - RTP-style 48kHz timestamp
Byte  6   : level_dbov (i8) - Audio level in dBov, clamped to –127..0
Byte  7   : flags (u8) - Bit 0 indicates FLAG_DTX (comfort noise)

```

In [`crates/buzz-relay/src/audio/wire.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/audio/wire.rs), the `FrameHeader::parse` function validates the buffer length, reads fields in **network-byte order**, clamps the `level_dbov` telemetry to prevent overflow attacks, and returns the header along with the remaining payload bytes. If the buffer is shorter than `FRAME_HEADER_LEN`, the function returns `None` and the relay **drops the malformed frame**.

For **protocol v3**, the system adds a second **epoch** byte to the wire format, allowing clients to detect and discard frames from previous session epochs.

## Broadcasting and Mesh Delivery

After parsing, `Room::broadcast_frame` constructs a peer-specific prefix and distributes the frame to all participants in the room.

The prefix format varies by protocol version:

- **v2 and earlier**: Single `peer_index` byte
- **v3**: Two-byte sequence of `peer_index` followed by `epoch`

The system prepends this prefix to the opaque Opus payload and transmits it via `mpsc::Sender` to each peer's audio channel (`AudioPeer::audio_tx`). The `try_send` operation is **non-blocking**; if a peer's buffer (capacity: 8 frames ≈ 160ms) is full, the relay drops that specific frame to preserve real-time performance rather than introducing backpressure.

### Mesh Pod Forwarding

In multi-pod deployments, when a frame arrives from another relay instance (the mesh layer), it already carries the correct `[peer_index][epoch?]` prefix. The `Room::deliver_prefixed` method forwards this frame to all local peers **except** the author identified by `author_index`, preventing self-echo while maintaining zero-copy forwarding semantics.

## Roster Management and State Recovery

The relay maintains an ordered **roster** of participants using `RosterPeer` and `RosterSnapshot` structures. Any membership change (join or leave) emits a `RosterDelta` on a Tokio broadcast channel subscribed to via `Room::subscribe_roster`.

If a client falls behind on delta processing, it can request a full `Room::roster_snapshot` and replay subsequent deltas with revision numbers greater than the snapshot's baseline. This mechanism makes the relay **stateless** regarding audio payloads while maintaining minimal metadata for routing and UI synchronization.

## Mesh-Aware Room Lookup

To prevent cross-community audio leakage in distributed deployments, the mesh layer performs room lookups using `AudioRoomManager::get_unambiguous_by_channel`, which searches **only by channel UUID**. If two distinct communities accidentally reuse the same channel UUID, the lookup fails closed rather than risking audio bleed between unrelated communities.

## Implementation Examples

### Client-Side Frame Transmission

```rust
// Establish WebSocket and authenticate (NIP-42)
let mut ws = connect_ws("/huddle/channel-uuid/audio").await?;

// Construct the 8-byte v2 header + Opus payload
let mut frame = BytesMut::with_capacity(8 + opus_data.len());
frame.extend_from_slice(&seq.to_be_bytes());        // u16 sequence
frame.extend_from_slice(&timestamp.to_be_bytes());  // u32 timestamp
frame.extend_from_slice(&[level_dbov, flags]);      // i8 + u8
frame.extend_from_slice(&opus_data);

// Send binary frame
ws.send(Message::Binary(frame.freeze())).await?;

```

### Server-Side Frame Handling

```rust
use buzz_relay::audio::{wire::FrameHeader, room::Room};

async fn handle_audio_stream(
    ws: WebSocket, 
    room: Arc<Room>, 
    peer_id: Uuid
) {
    while let Some(Ok(Message::Binary(bytes))) = ws.next().await {
        // Parse the 8-byte header
        if let Some((header, payload)) = FrameHeader::parse(&bytes) {
            // Broadcast to local peers (non-blocking)
            room.broadcast_frame(peer_id, payload).await;
            
            // Forward to mesh if this is a multi-pod setup
            mesh::forward_prefixed(room.channel_id(), header, payload);
        }
    }
}

```

### Receiving Mesh Frames

```rust
fn on_mesh_frame_received(
    channel_id: Uuid,
    author_index: u8,
    prefixed_frame: Bytes
) {
    if let Some(room) = audio_manager.get_unambiguous_by_channel(channel_id) {
        // Deliver to all local peers except the author
        room.deliver_prefixed(author_index, prefixed_frame);
    }
}

```

## Summary

- The **Huddle audio WebSocket Opus relay** in Buzz uses a three-layer architecture: WebSocket handlers, room management, and wire protocol parsing
- **Version pinning** in `Room::add_peer` ensures all participants use identical protocol versions, enforced by the `AdmissionGuard`
- The **8-byte v2 header** (sequence, timestamp, level, flags) is parsed in [`wire.rs`](https://github.com/block/buzz/blob/main/wire.rs) with strict validation and telemetry clamping
- **Non-blocking broadcast** via `mpsc::Sender` drops frames rather than delaying the real-time stream when buffers fill
- **Mesh support** uses `deliver_prefixed` to forward already-annotated frames between relay pods while preventing self-echo
- **Roster deltas and snapshots** provide eventual consistency for participant lists without holding audio state

## Frequently Asked Questions

### How does the Buzz relay handle protocol version mismatches?

When the first peer joins a room, `Room::add_peer` pins the protocol version to that peer's advertised version. Subsequent peers presenting different versions receive an `AdmissionError::VersionMismatch` and are rejected. This prevents incompatible clients from joining the same audio room.

### What happens when a peer's buffer is full during broadcasting?

The relay uses `try_send` on the `mpsc::Sender` channel with a capacity of 8 frames (approximately 160ms). If the channel is full, the frame is **dropped** rather than blocking the broadcaster. This preserves real-time performance for the entire room at the cost of occasional packet loss for slow consumers.

### How does the relay prevent audio from bleeding between communities?

The mesh layer in `AudioRoomManager::get_unambiguous_by_channel` looks up rooms **only by channel UUID**. If the UUID exists across multiple communities, the lookup fails closed to prevent cross-community audio leakage. This ensures strict isolation between unrelated social graphs.

### What is the purpose of the epoch byte in protocol v3?

The **epoch** byte increments each time a peer index is reused after a disconnect. Receiving clients use this value to fence stale frames that might arrive late from the previous occupant of that peer slot. This eliminates ghost audio from recently disconnected participants without requiring complex sequence tracking.