What is MoQT?
Media over QUIC Transport (MoQT) is an IETF protocol for delivering media and data over QUIC connections. It combines the low latency of real-time protocols with the scalability of relay-based distribution.
How MoQT works
MoQT follows a publish/subscribe model. Publishers send objects to a relay, which forwards them to all subscribed clients. Objects are organized into tracks (named streams within a namespace), and each track contains groups of objects. Clients subscribe to tracks with a filter that determines where to start receiving data — the latest object, the next group, or a specific position in history.
Objects flow from publishers through relays to subscribers over QUIC
What is MoQT used for?
Live streaming
Low-latency video and audio delivery. MoQT's group-based object model maps naturally to GOPs and audio segments, with built-in priority and delivery order controls.
Real-time chat & messaging
Publish/subscribe messaging over QUIC. Each chat room is a namespace, each conversation is a track, and each message is an object.
IoT telemetry
Sensor data ingestion over QUIC connections. MoQT handles high-frequency, small-payload publishing with efficient binary encoding and relay fan-out.
Game state synchronization
Real-time game state updates where priority and delivery order matter. MoQT lets publishers control which data is most important when bandwidth is constrained.
Core concepts
The building blocks of the MoQT protocol.
Tracks
A track is a named stream of objects within a namespace. Tracks are the fundamental unit of subscription — a client subscribes to a track to receive objects as they're published.
Namespace: ["chat", "room1"] — Track: "messages" Objects, Groups & Subgroups
An object is the smallest unit of data (a message, a video frame, a sensor reading). Objects are organized into groups (a GOP in video, a batch of messages) and optionally subgroups for priority ordering.
Group 42, Object 0: {"author": "alice", "msg": "hello!"} Subscriptions
Clients subscribe to tracks with a filter that determines where to start receiving: the latest object, the start of the next group, an absolute position, or a range of historical data.
SUBSCRIBE ns=["live"] track="video" filter=latest_group Relays
A relay is a server that receives objects from publishers and forwards them to subscribers. Relays can be chained, forming a distribution tree. They handle fan-out, subscription aggregation, and caching.
Publisher → Relay → Subscribers (fan-out) Sessions
A MoQT session runs over a single QUIC connection. The session starts with a CLIENT_SETUP / SERVER_SETUP handshake to negotiate the protocol version and capabilities.
CLIENT_SETUP versions=[draft-07] → SERVER_SETUP version=draft-07 QUIC Transport
MoQT runs over QUIC, which provides encrypted, multiplexed, low-latency transport. QUIC's stream multiplexing eliminates head-of-line blocking, and its built-in congestion control adapts to network conditions.
Bidirectional streams for control, unidirectional streams for data Control messages
MoQT sessions use a control stream for signaling. Key message types:
| Message | Purpose |
|---|---|
| CLIENT_SETUP / SERVER_SETUP | Negotiate protocol version and capabilities |
| SUBSCRIBE | Request objects from a track |
| SUBSCRIBE_OK / SUBSCRIBE_ERROR | Accept or reject a subscription |
| PUBLISH | Announce intent to publish a track |
| FETCH | Retrieve historical objects by range |
| SUBSCRIBE_NAMESPACE | Discover available tracks in a namespace |
| GOAWAY | Signal graceful session shutdown |
| UNSUBSCRIBE | Cancel an active subscription |
MoQT vs other protocols
| MoQT | WebRTC | HLS/DASH | WebSocket | |
|---|---|---|---|---|
| Transport | QUIC | DTLS/SRTP | HTTP/TCP | TCP |
| Topology | Relay-based | Peer-to-peer | CDN/server | Client-server |
| Latency | Sub-second | Sub-second | 5-30 seconds | Low |
| Fan-out | Native (relays) | SFU required | CDN | Manual |
| Priority control | Built-in | Limited | None | None |
| Pub/Sub model | Native | No | No | Manual |
Why is MoQT debugging hard?
- 1. QUIC encrypts everything — no passive packet capture without TLS key export
- 2. Binary encoding — MoQT messages are not human-readable on the wire
- 3. No browser DevTools support — Chrome shows WebTransport connections but not MoQT semantics
- 4. No Wireshark dissector — no existing tool decodes MoQT messages
- 5. Evolving spec — draft versions change message formats, so tools need multi-draft support
moqtap solves these problems by being a MoQT-aware client that connects to any relay and decodes everything for you.
MoQT explained
Focused answers to the questions implementers ask most about the wire protocol.
Track Namespace vs Track Name
The namespace is a tuple that groups tracks; the name identifies one track within it. How they differ and combine.
The SUBSCRIBE message
Field-by-field structure of SUBSCRIBE — filters, forward state, priority — with draft-17/18/19 differences.
SUBSCRIBE_NAMESPACE & prefix matching
How namespace discovery and track namespace prefix matching work, and the draft-18 SUBSCRIBE_TRACKS split.
Frequently asked questions
What is MoQT?
What is the difference between Track Namespace and Track Name in MoQT?
How is MoQT different from WebRTC?
How is MoQT different from HLS/DASH?
How is MoQT different from WebSocket?
What QUIC features does MoQT use?
Is MoQT finalized?
How do I debug MoQT?
Where can I learn more about MoQT?
See MoQT in action
Download moqtap and connect to a relay. See every message, every object, every transport metric.