Media Over QUIC S. Nandakumar Internet-Draft Cisco Intended status: Standards Track C. Jennings Expires: 1 September 2026 Cisco Systems 28 February 2026 ATOM: AT Protocol Over MoQ Transport draft-nandakumar-atproto-atom-00 Abstract This document specifies how the Authenticated Transfer (AT) Protocol can leverage Media over QUIC Transport (MOQT) for efficient data synchronization across decentralized social networks. The AT Protocol's firehose event stream and repository synchronization mechanisms map naturally to MOQT's publish/subscribe model, enabling scalable relay infrastructure, priority-based delivery, and improved resilience for large-scale social data distribution. This specification addresses the challenges of the current WebSocket- based transport and demonstrates how MOQT's relay architecture, group-based caching, and multiplexed streams provide significant benefits for AT Protocol deployments at scale. About This Document This note is to be removed before publishing as an RFC. The latest revision of this draft can be found at https://snandaku.github.io/draft-nandakumar-atproto-atom/draft- nandakumar-atproto-atom.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-nandakumar- atproto-atom/. Discussion of this document takes place on the Media Over QUIC Working Group mailing list (mailto:moq@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/moq/. Subscribe at https://www.ietf.org/mailman/listinfo/moq/. Source for this draft and an issue tracker can be found at https://github.com/snandaku/draft-nandakumar-atproto-atom. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 1 September 2026. Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction 1.1. Current AT Protocol Architecture 1.2. Requirements Language 2. Challenges with Current Transport 2.1. Scalability Limitations 2.1.1. Connection Overhead 2.1.2. Message Size Constraints 2.1.3. Single-Stream Bottleneck 2.2. Reliability Challenges 2.2.1. Cursor-Based Replay Limitations 2.2.2. No Native Late-Join Support 2.2.3. Connection Fragility 2.3. Operational Challenges 2.3.1. Relay Infrastructure Complexity 2.3.2. Limited Quality of Service 3. MOQT Transport Benefits 3.1. Native Publish/Subscribe Model 3.2. Priority-Based Delivery 3.3. Relay Infrastructure 3.4. Group-Based Organization and Caching 3.4.1. Late-Join via SUBSCRIBE 3.4.2. FETCH for On-Demand Retrieval 3.4.3. Caching Benefits Summary 3.5. QUIC Transport Advantages 4. MOQT Mapping 4.1. Connection Establishment 4.2. Track Types 4.2.1. Firehose Tracks 4.2.2. Repository Sync Tracks 4.2.3. Blob Store Track 4.3. Object Structure 4.4. Subscription and Filtering 4.4.1. Firehose Subscription 4.4.2. Repository Sync 4.4.3. Late-Join and Catch-Up 4.5. Priority and Parallelism 4.6. Relay Aggregation 5. Reliability and Recovery 5.1. Cursor Mapping 5.2. Gap Detection and Recovery 5.2.1. Detecting Missing Objects 5.2.2. Recovery: Fetch Missing Objects 5.2.3. Recovery: Fetch Full Group 5.2.4. Recovery: Full Repository Sync 5.3. Disconnection Handling 5.3.1. Brief Disconnections: 0-RTT Resumption 5.3.2. Extended Disconnections: Cursor-Based Reconnection 5.3.3. Network Transitions: Connection Migration 6. Authentication and Authorization 7. Security Considerations 8. IANA Considerations 9. References 9.1. Normative References 9.2. Informative References Authors' Addresses 1. Introduction The Authenticated Transfer (AT) Protocol [AT-ARCH] provides a framework for decentralized social web applications using self- certifying data repositories. The protocol enables users to maintain control over their data while participating in a federated network of Personal Data Servers (PDS), relays, and application views (AppViews). Currently, AT Protocol relies on two primary transport mechanisms for data synchronization: * *HTTP*: Used for batch repository exports via CAR (Content Addressable Archive) files * *WebSocket*: Used for real-time event streams (firehose) with CBOR-encoded messages While functional, these transport mechanisms face significant challenges at scale, particularly for the firehose event stream that must distribute updates across a network with millions of users generating billions of records. This document defines how Media over QUIC Transport (MOQT) [MoQ-TRANSPORT] can serve as an enhanced transport for AT Protocol. MOQT enables low-latency delivery while relay caching supports multiple latency spectrums from real-time to eventual consistency. The protocol's native publish/subscribe model, relay infrastructure, and priority-based delivery address current scalability and resilience challenges. 1.1. Current AT Protocol Architecture AT Protocol Network Architecture: ┌─────────────────┐ │ AppView │ │ (Indexer) │ │ │ └────────▲────────┘ │ Firehose (WS) │ ┌────────┴────────┐ │ Relay │ │ (Aggregator) │ └────────▲────────┘ │ ┌─────────────────────┼─────────────────────┐ │ │ │ ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐ │ PDS A │ │ PDS B │ │ PDS C │ │ (Hosts) │ │ (Hosts) │ │ (Hosts) │ │ - User 1 │ │ - User 2 │ │ - User 3 │ │ - User 2 │ │ - User 5 │ │ - User 6 │ └─────────────┘ └─────────────┘ └─────────────┘ The current architecture comprises: Personal Data Server (PDS): Hosts user accounts and their data repositories. Each PDS provides a firehose endpoint for real-time updates and HTTP endpoints for repository exports. Relay: Aggregates firehose streams from multiple PDS instances into a unified event stream. Full-network relays attempt to include all PDS instances in the network. AppView: Application-specific indexing services that consume the firehose to build aggregated views (e.g., feeds, search, analytics). 1.2. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 2. Challenges with Current Transport The current WebSocket-based transport for AT Protocol faces several challenges that impact scalability, reliability, and operational efficiency. 2.1. Scalability Limitations 2.1.1. Connection Overhead Each subscriber to a PDS or relay firehose requires a dedicated WebSocket connection. At network scale, this creates: * Connection state overhead on servers hosting popular content * TCP head-of-line blocking affecting all events on a connection * Limited ability to prioritize critical events during congestion 2.1.2. Message Size Constraints The current protocol specifies a hard maximum of 5 MBytes per WebSocket frame. While this accommodates most operations, it creates challenges for: * Large repository commits (limited to 2MB blocks, 200 operations) * Efficient batching of small updates * Variable-size content distribution 2.1.3. Single-Stream Bottleneck Current Firehose: Single Stream for All Event Types WebSocket Connection │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ #commit │ #commit │ #identity │ #commit │ #account │ #commit │ │ (big) │ (small) │ (urgent) │ (med) │ (urgent) │ (big) │ └─────────────────────────────────────────────────────────────────┘ │ ▼ Head-of-line blocking: Urgent #identity event must wait for large #commit to complete All event types flow through a single WebSocket stream without differentiation, meaning: * High-priority identity changes wait behind large commit events * Account status updates cannot preempt in-progress transfers * No mechanism for subscribers to filter by event type at transport layer 2.2. Reliability Challenges 2.2.1. Cursor-Based Replay Limitations The current firehose relies on monotonic cursor values for replay after disconnection. This approach requires consumers to track cursor state externally, since the protocol provides no mechanism for server-side cursor persistence. Gap detection depends entirely on commit chain validation, which is computationally expensive and requires maintaining local state. When gaps are detected, recovery requires fetching the complete repository, creating a thundering herd risk when many consumers reconnect simultaneously after an outage. 2.2.2. No Native Late-Join Support When a new consumer connects to a firehose, it must either start from the current position and miss all prior events, or replay from a cursor to catch up. There is no concept of "recent state" that would allow quick synchronization to a meaningful starting point. Consumers cannot receive cached recent events without initiating a full replay sequence, which increases latency for new subscribers and places additional load on the server. 2.2.3. Connection Fragility WebSocket connections over TCP are susceptible to network path changes that cause connection drops. The protocol provides no mechanism for connection migration when a client's IP address changes, such as when moving between networks on a mobile device. Any network transition requires establishing a completely new connection and resuming from the last known cursor position. 2.3. Operational Challenges 2.3.1. Relay Infrastructure Complexity Current relays face significant operational burden in maintaining the firehose infrastructure. Each relay must establish and maintain persistent WebSocket connections to all upstream PDS instances it aggregates, scaling linearly with the number of sources. When connections fail, relays must handle reconnection logic and cursor tracking independently for each upstream source. Custom caching and replay logic must be implemented at the application layer, as the transport provides no native support for these operations. Additionally, relays must build proprietary distribution mechanisms to serve their own downstream subscribers, duplicating effort across the ecosystem. 2.3.2. Limited Quality of Service The current transport provides no native mechanism for quality of service differentiation. All event types receive equal treatment regardless of their operational importance, so critical account status changes compete with routine content updates for bandwidth. Rate limiting based on consumer capacity must be implemented entirely at the application layer, with no transport-level flow control. Graceful degradation during overload conditions is difficult to achieve, often resulting in connection failures rather than controlled service reduction. 3. MOQT Transport Benefits MOQT addresses the challenges identified above through its native architecture designed for large-scale media distribution. 3.1. Native Publish/Subscribe Model MOQT's publish/subscribe model aligns naturally with AT Protocol's firehose semantics. Subscribers select specific event tracks of interest while publishers announce available tracks via PUBLISH_NAMESPACE. Since relays handle distribution, no dedicated connection is required per subscriber, and track-level subscription granularity reduces unnecessary traffic. PUBLISH_NAMESPACE enables dynamic discovery of available content. When a PDS comes online, it announces its namespaces to connected relays, advertising firehose tracks, repository sync tracks, and blob stores. Relays learn about new PDS instances automatically without static configuration, enabling the network to scale organically as new servers join. SUBSCRIBE_NAMESPACE allows subscribers to discover available tracks using prefix-based queries. A full-network relay can subscribe to at/firehose/ to discover all PDS instances publishing firehose events, then selectively subscribe to each. An AppView can query a relay's namespace to enumerate available event types before subscribing to specific tracks of interest. This discovery mechanism eliminates the need for out-of-band coordination when adding new publishers or subscribers to the network. A PDS advertises its available namespaces via PUBLISH_NAMESPACE: +=============================+===============================+ | Namespace | Description | +=============================+===============================+ | at/firehose/pds.example.com | Firehose events from this PDS | +-----------------------------+-------------------------------+ | at/repo/pds.example.com | Repository sync tracks | +-----------------------------+-------------------------------+ | at/blobs/pds.example.com | Blob storage | +-----------------------------+-------------------------------+ Table 1 A relay discovering PDS instances issues SUBSCRIBE_NAMESPACE with at/ firehose/ and receives a NAMESPACE response listing all matching hosts (potentially thousands of PDS instances). 3.2. Priority-Based Delivery MOQT's 0-255 priority scale enables differentiated event delivery, ensuring that critical account takedowns (priority 0-15) and urgent identity changes such as key rotations (priority 16-31) are delivered ahead of routine commit events (priority 96-191). This prevents large content transfers from blocking time-sensitive operations. +=====================+===============+========================+ | AT Event Type | MOQT Priority | Rationale | +=====================+===============+========================+ | #account (takedown) | 0-15 | Critical - affects | | | | content availability | +---------------------+---------------+------------------------+ | #identity | 16-31 | Urgent - key rotation, | | | | handle changes | +---------------------+---------------+------------------------+ | #account (status) | 32-63 | Important - account | | | | state changes | +---------------------+---------------+------------------------+ | #sync | 64-95 | Moderate - state reset | | | | events | +---------------------+---------------+------------------------+ | #commit (small) | 96-127 | Normal - typical | | | | record operations | +---------------------+---------------+------------------------+ | #commit (large) | 128-191 | Background - bulk | | | | content updates | +---------------------+---------------+------------------------+ | Repository export | 192-255 | Bulk - full sync | | | | operations | +---------------------+---------------+------------------------+ Table 2 3.3. Relay Infrastructure MOQT relays provide purpose-built infrastructure for AT Protocol distribution. Hierarchical relay topologies reduce origin load by distributing cached content from regional nodes, while geographic placement optimizes latency for subscribers. Because the relay protocol is standardized, operators need not implement custom distribution logic. MOQT Relay Network for AT Protocol: ┌─────────────────┐ │ Global Relay │ │ (Federation) │◄─── Cross-region aggregation └────────┬────────┘ │ ┌─────────────────┼─────────────────┐ │ │ │ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ │ Regional │ │ Regional │ │ Regional │ │ Relay A │ │ Relay B │ │ Relay C │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ │ │ │ │ │ │ PDS 1 PDS 2 PDS 3 PDS 4 PDS 5 PDS 6 ▲ ▲ ▲ ▲ ▲ ▲ │ │ │ │ │ │ Users Users Users Users Users Users 3.4. Group-Based Organization and Caching MOQT groups enable efficient caching and late-join support. Late- joining subscribers receive the most recent group immediately rather than replaying from the beginning, and relay caches at each tier reduce upstream load. Group boundaries serve as natural replay points, with cursor semantics mapping directly to Group ID and Object ID. Group Hierarchy: [G0: events 0-99] [G1: events 100-199] ... [GN: live] ↓ ↓ ↓ Relay Cache: cached cached caching 3.4.1. Late-Join via SUBSCRIBE MOQT's SUBSCRIBE message includes filter parameters that control the starting position for delivery. As defined in [MoQ-TRANSPORT], these filters include LatestGroup (start from the newest available group), LatestObject (start from the most recent object), AbsoluteStart (begin at a specific group/object position), and AbsoluteRange (request a bounded range). These filters allow subscribers to join at any point and then continue receiving live and future content. SUBSCRIBE delivers content from the specified starting position forward, keeping subscribers at the live edge as new content arrives. For historical content retrieval, subscribers use FETCH operations instead (see Section 3.4.2). This capability supports several AT Protocol scenarios. A new subscriber joining a track uses LatestGroup to begin with current activity. 3.4.2. FETCH for On-Demand Retrieval MOQT's FETCH operation complements SUBSCRIBE by enabling selective retrieval of specific objects. While SUBSCRIBE keeps clients at the live edge, FETCH retrieves historical content regardless of how far back it exists. FETCH specifies exact group and object ranges, retrieving precisely the needed data without establishing a continuous subscription. When a subscriber detects a gap in received events, it can FETCH the missing objects directly rather than replaying an entire group. When verifying a specific record, a client can FETCH just the MST path blocks needed for cryptographic validation. For deep historical queries, an analytics service can FETCH specific commit ranges from months prior. Relay caching amplifies the benefit of FETCH operations. Popular content such as viral images, high-profile account commits, and frequently accessed MST nodes remain in relay cache. Subsequent FETCH requests for this content are served locally, reducing latency and eliminating load on origin servers. For a viral post with an embedded image, thousands of FETCH requests for the image blob resolve to a single origin fetch followed by cache hits at the relay tier. 3.4.3. Caching Benefits Summary The combination of SUBSCRIBE late-join and FETCH with relay caching provides several benefits for AT Protocol deployments: * Fan-out efficiency: Origin publishes once, relay serves many subscribers * Late-join speed: New subscribers receive cached history immediately * Gap recovery: Missing events fetched from relay cache, not origin * Popular content: High-demand blobs and commits served from cache * Reduced origin load: Relay tier absorbs read amplification 3.5. QUIC Transport Advantages Leveraging QUIC [RFC9000] provides connection migration so that firehose subscriptions survive network changes such as IP address transitions or WiFi-to-cellular handoffs. Multiplexed streams eliminate head-of-line blocking between logical channels, while mandatory TLS 1.3 [RFC8446] ensures built-in encryption. Per-stream and connection-level flow control prevents subscriber overload, and 0-RTT resumption enables fast reconnection after brief disconnections. 4. MOQT Mapping This section defines how AT Protocol data maps to MOQT primitives. 4.1. Connection Establishment AT Protocol endpoints using MOQT establish connections following the standard MOQT setup procedure: AT-over-MOQT Connection Establishment: PDS/Relay Subscriber │ │ │◄─── QUIC Connection (ALPN: "moqt") ─────────────────│ │──── QUIC Connection Established ───────────────────▶│ │ │ │◄─── MOQT CLIENT_SETUP ──────────────────────────────│ │ (at-version: 1, supported-events: 0x0F) │ │ │ │──── MOQT SERVER_SETUP ─────────────────────────────▶│ │ (at-version: 1, relay-capabilities: 0x07) │ │ │ │──── PUBLISH_NAMESPACE ─────────────────────────────▶│ │ (at/{pds-host}/firehose) │ │ │ │◄─── SUBSCRIBE_NAMESPACE ────────────────────────────│ │ (at/{pds-host}/firehose) │ │ │ │──── NAMESPACE (tracks available) ──────────────────▶│ │ (commits, identity, account, sync) │ │ │ │◄─── SUBSCRIBE (commits) ────────────────────────────│ │ │ │──── SUBSCRIBE_OK ──────────────────────────────────▶│ │ │ │═════ Firehose Event Stream ════════════════════════▶│ Setup parameters for AT Protocol: +=====================+============+========+======================+ | Parameter | ID | Type | Description | +=====================+============+========+======================+ | at-version | 0x41540001 | varint | AT Protocol version | +---------------------+------------+--------+----------------------+ | at-supported-events | 0x41540002 | varint | Bitmask of supported | | | | | event types | +---------------------+------------+--------+----------------------+ | at-relay-caps | 0x41540003 | varint | Relay capability | | | | | flags | +---------------------+------------+--------+----------------------+ Table 3 Event type bitmask values: 0x01 (#commit), 0x02 (#identity), 0x04 (#account), 0x08 (#sync). 4.2. Track Types ATOM defines three track types for different use cases: 4.2.1. Firehose Tracks Firehose tracks carry real-time event streams from PDS hosts. Namespace structure: at/firehose/{host}/{event-type} -- {did|all} +==========+============================+============+==========+ | Track | Namespace | Content | Priority | +==========+============================+============+==========+ | Commits | at/firehose/{host}/commits | Repository | 96-191 | | | | updates | | +----------+----------------------------+------------+----------+ | Identity | at/ | DID/handle | 16-31 | | | firehose/{host}/identity | changes | | +----------+----------------------------+------------+----------+ | Account | at/firehose/{host}/account | Hosting | 0-63 | | | | status | | +----------+----------------------------+------------+----------+ | Sync | at/firehose/{host}/sync | State | 64-95 | | | | assertions | | +----------+----------------------------+------------+----------+ Table 4 Groups organize events by sequence number (e.g., 1000 events per group). Track name is either a specific DID or "all" for aggregated streams. 4.2.2. Repository Sync Tracks Repository sync tracks provide full block-level repository data. Namespace: at/repo/{host}/{did}/sync The MOQT hierarchy maps to AT Protocol repository concepts: +============+=======================+=========================+ | MOQT Level | AT Protocol Concept | Purpose | +============+=======================+=========================+ | Track | Repository (DID) | Subscription unit | +------------+-----------------------+-------------------------+ | Group | Commit/Revision | Temporal progression | +------------+-----------------------+-------------------------+ | Subgroup | Collection + MST path | Structural organization | +------------+-----------------------+-------------------------+ | Object | Record/Block | Individual data items | +------------+-----------------------+-------------------------+ Table 5 Each group represents a commit. Subgroup 0 contains the signed commit and MST structure; subsequent subgroups contain collections with MST proof paths for independent verification. +==========+===============================================+ | Subgroup | Contents | +==========+===============================================+ | 0 | Commit block + full MST (verification anchor) | +----------+-----------------------------------------------+ | 1+ | Collection records + MST proof path | +----------+-----------------------------------------------+ Table 6 Objects within a group are ordered: signed commit (ObjectID 0), MST root, MST intermediate nodes, then records. The at-block-cid extension header carries the CID for integrity verification. MST Structure and MOQT Mapping: Repository (DID: did:plc:abc123) │ ├── Commit (rev: 3kf7x2...) ──────────────▶ Group N │ │ │ ├── Signed Commit Block ──────────────▶ Subgroup 0, Object 0 │ │ │ └── MST (Merkle Search Tree) │ │ │ ├── Root Node (CID: bafyr...)──────────────▶ Subgroup 0, Object 1 │ │ ├── key: "app.bsky.feed.post/3k..." │ │ └── children: [L, R] │ │ │ ├── Left Node ───────────────▶ Subgroup 0, Object 2 │ │ └── key: "app.bsky.actor.profile/self" │ │ │ └── Right Node ───────────────▶ Subgroup 0, Object 3 │ └── key: "app.bsky.graph.follow/3k..." │ ├── Collection: app.bsky.feed.post ──────────────▶ Subgroup 1 │ ├── Record 3k7abc... + MST proof ──────────────▶ Object 0 │ └── Record 3k7def... + MST proof ──────────────▶ Object 1 │ ├── Collection: app.bsky.actor.profile ────────────▶ Subgroup 2 │ └── Record self + MST proof ──────────────▶ Object 0 │ └── Collection: app.bsky.graph.follow ─────────────▶ Subgroup 3 └── Record 3k9xyz... + MST proof ──────────────▶ Object 0 The MST proof path included with each record contains the minimal set of tree nodes required to verify that record's inclusion in the commit. This enables independent verification of individual records without downloading the entire repository. 4.2.3. Blob Store Track Blob store tracks enable cross-repository deduplication of large media. Namespace: at/blobs/{host} The Group ID is derived from the CID (first 8 bytes of multihash as uint64), Object ID is always 0. This deterministic mapping ensures identical blobs from different repositories resolve to the same MOQT location. 4.3. Object Structure AT Protocol events are encapsulated in MOQT objects: MOQT Object Structure: ┌─────────────────────────────────────────────────────────────┐ │ Extension Headers: │ │ at-event-type (0x41544501): varint │ │ at-repo-did (0x41544502): string │ │ at-repo-rev (0x41544503): string (TID) │ │ at-seq (0x41544504): varint (cursor equivalent) │ │ at-block-cid (0x41544505): bytes (for repo sync blocks) │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ Payload: CBOR-encoded event (compatible with AT-REPO) │ └─────────────────────────────────────────────────────────────┘ 4.4. Subscription and Filtering 4.4.1. Firehose Subscription Subscribers specify start position and filtering: * StartGroup=Latest: Begin with live events (default) * StartGroup=N: Resume from specific cursor position * Track name all or specific DID for filtering 4.4.2. Repository Sync Subgroup filtering enables selective synchronization: Selective Sync Examples: Full repository: SubgroupFilter: [0, 1, 2, 3, ...] Posts only: SubgroupFilter: [0, 1] (~15% bandwidth) Verification only: SubgroupFilter: [0] (~2% bandwidth) Temporal navigation with groups: * Subscribe StartGroup=LATEST: Current state + live updates * Fetch StartGroup=N, EndGroup=M: Historical range retrieval 4.4.3. Late-Join and Catch-Up New subscribers request StartGroup=LATEST to receive current state immediately. After disconnection, subscribers use Fetch with their last known group to retrieve missed commits before resuming live subscription. 4.5. Priority and Parallelism MOQT priority enables efficient delivery ordering: +==================+==========+=============================+ | Block Type | Priority | Rationale | +==================+==========+=============================+ | Account takedown | 0-15 | Safety-critical | +------------------+----------+-----------------------------+ | Identity changes | 16-31 | Affects routing | +------------------+----------+-----------------------------+ | Signed Commit | 0-15 | Required for verification | +------------------+----------+-----------------------------+ | MST Root | 16-31 | Unlocks tree traversal | +------------------+----------+-----------------------------+ | MST Nodes | 32-63 | Enables record verification | +------------------+----------+-----------------------------+ | Small Records | 64-127 | Core content | +------------------+----------+-----------------------------+ | Large Records | 128-191 | Less urgent | +------------------+----------+-----------------------------+ | Blobs | 192-255 | Media, lazy-loadable | +------------------+----------+-----------------------------+ Table 7 Content-addressable blocks enable parallel fetching across QUIC streams, with total transfer time bounded by the slowest stream rather than the sum of all transfers. 4.6. Relay Aggregation MOQT relays aggregate firehose streams from multiple upstream sources: Relay Aggregation: Full-Network Relay ┌────────────────────┐ │ at/firehose/ │ │ relay.network/* │ └─────────▲──────────┘ │ ┌────────────────────┼────────────────────┐ │ │ │ ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐ │ Regional │ │ Regional │ │ Regional │ │ Relay │ │ Relay │ │ Relay │ └──────▲──────┘ └──────▲──────┘ └──────▲──────┘ │ │ │ PDS hosts PDS hosts PDS hosts Relays perform subscription aggregation, namespace republishing, event caching for late-join, and deduplication. 5. Reliability and Recovery ATOM leverages MOQT's group-based delivery model and QUIC's transport features to provide robust reliability mechanisms for AT Protocol data synchronization. The key capabilities include cursor mapping that translates AT Protocol sequence numbers to MOQT group/object positions, gap detection that identifies missing events through sequential object tracking, and multiple recovery strategies ranging from targeted object fetches to full repository synchronization. QUIC's connection migration further ensures that subscribers maintain continuous delivery even when network conditions change. 5.1. Cursor Mapping AT Protocol cursors map to MOQT group and object identifiers, enabling seamless translation between the existing cursor-based replay mechanism and MOQT's hierarchical addressing. Each firehose track maintains a mapping table that records the sequence number base for each group, allowing bidirectional conversion between AT Protocol cursors and MOQT positions. When a subscriber needs to resume from a specific cursor position, it converts the cursor value to the corresponding group and object identifiers. The conversion uses integer division to determine the group number and the modulo operation to determine the object offset within that group. This deterministic mapping ensures that any cursor value can be precisely located within the MOQT track structure. Cursor Translation: AT Cursor (seq: 12345678) │ ▼ ┌────────────────────────────────────────┐ │ Cursor Mapping Table (per track) │ │ │ │ seq_base: 12340000 │ │ group_size: 1000 │ │ │ │ seq 12345678 │ │ = seq_base + (group * group_size) │ │ + object │ │ = 12340000 + (5 * 1000) + 678 │ │ │ │ MOQT: Group 5, Object 678 │ └────────────────────────────────────────┘ Publishers MUST include the at-seq extension header in each object to enable accurate cursor reconstruction. 5.2. Gap Detection and Recovery MOQT's group-based delivery model simplifies gap detection compared to the current cursor-only approach. This section describes how gaps are detected and the recovery strategies available to subscribers. 5.2.1. Detecting Missing Objects Because objects within a group are sequentially numbered and groups themselves are ordered, subscribers can immediately identify when expected objects are missing by comparing received object identifiers against their expected sequence. Gap Detection: Subscriber State: Last received: Group 5, Object 999 Expected next: Group 6, Object 0 Incoming object: Group 6, Object 5 Expected Received │ │ ▼ ▼ ┌─────────┐ ┌─────────┐ │ G6, O0 │ ← Missing! → │ G6, O5 │ └─────────┘ └─────────┘ │ ▼ Gap detected: Objects 0-4 missing from Group 6 5.2.2. Recovery: Fetch Missing Objects The preferred recovery approach is to fetch only the specific missing objects using MOQT's FETCH operation with precise group and object boundaries. If relay caches contain the missing data, recovery completes without any load on the origin server. Fetch Missing Objects: Subscriber Relay Origin │ │ │ │── FETCH ────────────────────────▶│ │ │ StartGroup=6, StartObject=0 │ │ │ EndGroup=6, EndObject=4 │ │ │ │ │ │ [Cache hit?] │ │ │ Yes │ │◄── Objects 0-4 ──────────────┘ │ │ (from cache) │ │ │ │ Gap filled, resume live stream │ 5.2.3. Recovery: Fetch Full Group For larger gaps spanning multiple groups, subscribers may request entire groups rather than specifying individual object ranges. This approach is simpler but may retrieve more data than strictly necessary. Fetch Full Group: Subscriber Relay Origin │ │ │ │ [Gap spans Groups 6-8] │ │ │ │ │ │── FETCH ────────────────────────▶│ │ │ StartGroup=6, EndGroup=8 │ │ │ │ │ │ [Partial cache] │ │◄── Group 6 (cached) ─────────────┤ │ │◄── Group 7 (cached) ─────────────┤ │ │ │── FETCH ──────────────▶│ │ │ (Group 8) │ │ │◄── Group 8 ────────────│ │◄── Group 8 ──────────────────────┤ │ │ │ │ All groups received, resume live stream │ 5.2.4. Recovery: Full Repository Sync As a fallback when cached data is unavailable or gaps are too extensive, subscribers can perform a full repository synchronization using either HTTP CAR exports or the MOQT repository sync track. This approach validates the entire repository state against a #sync event. Full Repository Sync: Subscriber PDS/Relay │ │ │ [Gap too large or cache miss] │ │ │ │── GET /xrpc/com.atproto.sync. ──▶│ │ getRepo?did=... │ │ │ │◄── CAR file ─────────────────────│ │ (complete repository export) │ │ │ │ [Validate against #sync event] │ │ │ │ 1. Parse CAR blocks │ │ 2. Verify MST root matches │ │ 3. Update local state │ │ 4. Resume live subscription │ 5.3. Disconnection Handling MOQT over QUIC provides superior disconnection handling through three complementary mechanisms: 0-RTT session resumption, cursor-based reconnection, and transparent connection migration. 5.3.1. Brief Disconnections: 0-RTT Resumption For brief disconnections (typically under 30 seconds), QUIC's 0-RTT resumption allows subscribers to restore their session with minimal latency. The subscriber presents a session ticket from the previous connection, and the relay resumes delivery from where it left off if the cached session state remains valid. This typically completes in a single round trip. QUIC 0-RTT Resumption: Subscriber Relay │ │ │ [Connection lost briefly] │ │ │ │ [Reconnecting with session ticket] │ │ │ │── QUIC 0-RTT ────────────────────────▶│ │ ClientHello + session ticket │ │ + early data (SUBSCRIBE) │ │ │ │◄── ServerHello + Finished ────────────│ │ │ │◄── Continue from last position ───────│ │ (relay cached subscriber state) │ │ │ │══ Resume live stream (minimal gap) ══▶│ 5.3.2. Extended Disconnections: Cursor-Based Reconnection For extended disconnections where session state has expired, subscribers perform a full reconnection using their saved cursor position. The subscriber first uses FETCH to retrieve any missed events from their last known position, then establishes a new SUBSCRIBE starting from the latest group to receive live updates. Relay caches serve the historical data when available, minimizing load on upstream servers. Full Reconnection with Cursor: Subscriber Relay │ │ │ [Disconnected for extended period] │ │ [Saved state: at-seq = 12345678] │ │ │ │── QUIC Handshake (full) ─────────────▶│ │◄── Connection Established ────────────│ │ │ │── CLIENT_SETUP ──────────────────────▶│ │◄── SERVER_SETUP ──────────────────────│ │ │ │ [Convert cursor to Group/Object] │ │ seq 12345678 → Group 5, Object 678 │ │ │ │── FETCH ─────────────────────────────▶│ │ StartGroup=5, StartObject=678 │ │ EndGroup=LATEST │ │ │ │◄── Historical objects (cached) ───────│ │ │ │── SUBSCRIBE ─────────────────────────▶│ │ StartGroup=LATEST │ │◄── SUBSCRIBE_OK ──────────────────────│ │ │ │══ Live stream resumes ═══════════════▶│ 5.3.3. Network Transitions: Connection Migration For network transitions such as WiFi-to-cellular handoffs, QUIC's connection migration enables seamless continuation without any application-layer intervention. The subscriber's IP address changes transparently while the MOQT session continues uninterrupted, ensuring no gaps in the event stream during mobile network transitions. QUIC Connection Migration: Subscriber (mobile) Relay │ │ │══ Streaming on WiFi ═════════════════▶│ │ (IP: 192.168.1.50) │ │ │ │ [User moves, WiFi signal lost] │ │ [Device switches to cellular] │ │ [New IP: 10.0.0.75] │ │ │ │── QUIC PATH_CHALLENGE ───────────────▶│ │ (from new IP address) │ │ │ │◄── QUIC PATH_RESPONSE ────────────────│ │ (path validated) │ │ │ │══ Continue streaming on cellular ════▶│ │ (no gap, no reconnection needed) │ │ │ │ [Application layer unaware of │ │ network transition] │ 6. Authentication and Authorization TODO 7. Security Considerations TODO 8. IANA Considerations TODO 9. References 9.1. Normative References [AT-ARCH] Newbold, B. and D. Holmgren, "Authenticated Transfer (AT) Protocol Architecture", Work in Progress, Internet-Draft, draft-newbold-at-architecture, 2025, . [AT-REPO] Holmgren, D. and B. Newbold, "Authenticated Transfer (AT) Repository and Synchronization", Work in Progress, Internet-Draft, draft-holmgren-at-repository, 2025, . [MoQ-TRANSPORT] Curley, L., Pugin, K., Nandakumar, S., Vasiliev, V., and I. Swett, "Media over QUIC Transport", Work in Progress, Internet-Draft, draft-ietf-moq-transport-16, January 2026, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, . [RFC9000] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, May 2021, . 9.2. Informative References [MoQ-C4M] Jennings, S., "Common Access Token for Media over QUIC", Work in Progress, Internet-Draft, draft-ietf-moq-c4m, 2025, . [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext Transfer Protocol Version 2 (HTTP/2)", RFC 7540, DOI 10.17487/RFC7540, May 2015, . [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, . [WebTransport] Vasiliev, V., "The WebTransport Protocol Framework", RFC 9297, August 2023, . Authors' Addresses Suhas Nandakumar Cisco Email: snandaku@cisco.com Cullen Jennings Cisco Systems Email: fluffy@cisco.com