How a domain name is encoded on the wire

A domain isn't sent as text with dots — each label gets a length byte, and the dots disappear.

The idea

When a DNS query travels over the network, the name www.example.com is not written as a string with dots. The dots never appear in the bytes at all. Instead the name is split at each dot into labels (www, example, com), and every label is preceded by a single byte that says how long it is.

After the last label, a single zero byte marks the end of the name — that 00 represents the invisible root of the DNS tree. This length-prefixed format (RFC 1035) is what we encode below, one byte at a time.

human name wire bytes
Ready to encode www.example.com. Press play or step forward.

How it works

Split the name on its dots, then for each label write one length byte followed by the label's ASCII bytes. Finish with a single zero byte for the root label.

function encodeName(name) {
  const out = [];
  for (const label of name.split('.')) {
    if (label === '') continue;        // skip empty (e.g. trailing dot)
    out.push(label.length);            // 1 length byte (1..63)
    for (const ch of label)
      out.push(ch.charCodeAt(0));      // the label's ASCII bytes
  }
  out.push(0);                         // terminating root label
  return out;                          // array of byte values
}
// encodeName("www.example.com")
// -> [3, 119,119,119, 7, 101,120,97,109,112,108,101, 3, 99,111,109, 0]

Cost

The encoder visits each character once, so it runs in O(n) time for a name of length n. The wire size is easy to predict:

QuantityValue for www.example.com
Name characters (without dots)13 (www + example + com)
Length bytes (one per label)3
Terminating zero byte1
Total wire size17 bytes

In general: wire size = (characters without dots) + (number of labels) + 1.

Watch out for

Worked example

Encoding www.example.com gives 17 bytes. Reading left to right, each length byte (shown in bold) tells you how many character bytes follow before the next length byte:

03 77 77 77      3 bytes: w w w
07 65 78 61 6d   7 bytes: e x a m
   70 6c 65               p l e
03 63 6f 6d      3 bytes: c o m
00               root label, end of name

That is 1 + 3 + 1 + 7 + 1 + 3 + 1 = 17 bytes. No dot ever appears in the stream — its job is done by the length bytes that separate one label from the next.

Check yourself

How many bytes does the name a.bc encode to?

What does the trailing 0x00 byte mean at the end of an encoded name?