MoQT explained

Track Namespace vs Track Name

In Media over QUIC Transport (MoQT), the Track Namespace is an ordered tuple of byte-string components that groups related tracks — e.g. ["chat", "room1"]. The Track Name is a single byte string that identifies one track within that namespace — e.g. "messages". The namespace is the folder; the name is the file. Together they form the Full Track Name, which uniquely identifies a track.

The key behavioral difference: the namespace supports prefix matching for discovery, while the name is always matched exactly.

Applies to draft-ietf-moq-transport drafts 07–19 (current: draft-19).

Side by side

Track Namespace Track Name
What it is An ordered tuple of byte-string components that groups related tracks A single byte string that identifies one track within a namespace
Wire type Tuple (count + length-prefixed components) Length-prefixed bytes
Example ["chat", "room1"] "messages"
Cardinality One namespace holds many tracks One name per track inside its namespace
Used for Discovery & announcement — prefix matching in SUBSCRIBE_NAMESPACE; carried in PUBLISH_NAMESPACE / NAMESPACE Addressing a specific track in SUBSCRIBE / FETCH / PUBLISH
Supports prefix matching Yes — a prefix tuple matches every namespace that starts with it No — matched exactly

The Full Track Name

Neither the namespace nor the name is unique on its own. Two different namespaces can each contain a track called "video", and one namespace contains many differently-named tracks. What uniquely identifies a track is the pair — the Full Track Name:

Full Track Name = ( Track Namespace , Track Name )
                 = ( ["sports","live","game42"] , "video" )

Because repeating a full namespace tuple and name on every object would be wasteful, MoQT assigns each subscribed track a compact integer Track Alias. Control messages carry the Full Track Name; the data streams that follow reference the track by its alias. (Exactly where the alias is assigned has shifted across drafts — see the message-type reference for the byte-level layout in a specific draft.)

Where each one appears

The distinction is easiest to see by which control messages use which field:

Message Track Namespace Track Name Role
SUBSCRIBE Full tuple Exact name Identifies the one track to receive objects from
FETCH Full tuple Exact name Identifies the track to pull historical objects from
PUBLISH Full tuple Exact name Announces a specific track a publisher will serve
SUBSCRIBE_NAMESPACE Prefix tuple — (not used) Registers interest in a namespace prefix; no track name
PUBLISH_NAMESPACE Full tuple — (not used) A publisher advertises that it has tracks in a namespace
NAMESPACE Suffix tuple — (not used) The relay’s response to SUBSCRIBE_NAMESPACE — carries the namespace suffix after your prefix (draft-17+)

Note the last two rows: namespace-discovery messages use only the namespace (as a prefix), never a track name.

Why the namespace is a tuple: prefix matching

The namespace being an ordered tuple — rather than a flat string — is what makes discovery work. A subscriber sends SUBSCRIBE_NAMESPACE with a prefix tuple, and the relay announces every namespace that begins with it — as NAMESPACE messages carrying the suffix after your prefix (draft-17+):

TX  SUBSCRIBE_NAMESPACE  prefix = ["sports"]
RX  REQUEST_OK

RX  NAMESPACE           ["live","game42"]   ✓ matches → suffix after ["sports"]
RX  NAMESPACE           ["vod","game17"]    ✓ matches
    (not announced)     ["news"]            ✗ no match

(NAMESPACE is the response to a subscription; don't confuse it with PUBLISH_NAMESPACE, which a publisher sends to advertise a namespace.) A track name has no such structure — it is one opaque byte string, matched exactly. For the full discovery flow, see SUBSCRIBE_NAMESPACE and track namespace prefix matching.

Common mistakes

  • Flattening the namespace to a string. "sports/live/game42" is not the same as the tuple ["sports","live","game42"]. The tuple boundaries are what prefix matching keys on; a slash-joined string loses them.
  • Putting the track name in the namespace. A SUBSCRIBE needs both fields; folding "video" into the namespace tuple means no track name to subscribe to.
  • Expecting a track name to prefix-match. Only the namespace does. A "track does not exist" error after a SUBSCRIBE is usually a name that does not match exactly.

Frequently asked questions

What is the difference between Track Namespace and Track Name in MoQT?
The Track Namespace is an ordered tuple of byte-string components that groups related tracks (for example ["chat", "room1"]). The Track Name is a single byte string that identifies one track inside that namespace (for example "messages"). The namespace is the folder; the name is the file. Together they form the Full Track Name, which uniquely identifies a track. The namespace supports prefix matching for discovery; the name is always matched exactly.
What is a Track Namespace in MoQT?
A Track Namespace is an ordered tuple of one or more byte-string components — like ["sports", "live", "game42"] — used to group related tracks and to discover them. Because it is a tuple, a subscriber can register interest in a prefix such as ["sports"] via SUBSCRIBE_NAMESPACE and receive announcements for every namespace that begins with it.
What is a Track Name in MoQT?
A Track Name is a byte string that names one specific track within a Track Namespace — for example "video", "audio", or "messages". It is carried in SUBSCRIBE, FETCH, and PUBLISH alongside the namespace, and it is always matched exactly (unlike the namespace, which supports prefix matching).
What is the Full Track Name in MoQT?
The Full Track Name is the pair (Track Namespace, Track Name) taken together. It is the globally unique identifier for a track. On the wire, data streams reference a track by a compact integer Track Alias instead of repeating the full namespace and name on every object.
Does the Track Namespace / Track Name split change between MoQT draft versions?
The concept is stable from draft-07 through draft-19 of draft-ietf-moq-transport: the namespace is a tuple, the name is a byte string, and the two combine into the Full Track Name. What has moved across drafts is the surrounding machinery — for example the draft-18 split of SUBSCRIBE_NAMESPACE into SUBSCRIBE_NAMESPACE and SUBSCRIBE_TRACKS — not the definition of namespace vs name itself.

Related

See namespaces and tracks on the wire

moqtap decodes every SUBSCRIBE, SUBSCRIBE_NAMESPACE, and PUBLISH_NAMESPACE — showing the exact namespace tuple and track name your implementation sent, across drafts 07–19.