How email threading actually works

A mail thread is not something the protocol stores. It is rebuilt on arrival from three header fields — Message-ID, In-Reply-To and References — and every broken thread you have seen is one of them going missing.

5 min read

Your mail client shows you a conversation. The protocol underneath it has no concept of one. Every message is an independent delivery, and what you see as a thread was reconstructed on your machine, from your copies, using three header fields any link in the chain is free to mangle.

That gap explains nearly every threading complaint anyone has had.

The three headers that carry ancestry

Message-ID is a globally unique identifier for one message, written as an angle-bracketed string shaped like an address — a locally unique left part, an at sign, a domain vouching for uniqueness. The composing client normally generates it; if not, the first server to handle it usually will. The internet message format standard (RFC 5322) says every message should carry one, and it is never meant to be reused.

In-Reply-To holds the Message-ID of the message being answered. The standard allows several, for a reply answering more than one parent, but one is ordinary.

References holds the ancestry chain, and the rule is worth memorising: a reply's References is the parent's References with the parent's own Message-ID appended. Oldest first. The fifth message in a conversation lists the four before it, in order.

The difference between References and In-Reply-To is the difference between a whole thread and a single link. That is where most breakage lives.

How a client rebuilds a conversation

A client indexes everything it holds by Message-ID. When a message arrives, it reads References and walks backwards from the most recent identifier, looking for the first one it recognises, then hangs the arriving message off that node. If nothing matches, In-Reply-To is the fallback. If that fails too, the message becomes a root of its own — or is attached by a subject heuristic, if the client has one.

The reference implementation most people are unknowingly familiar with is Jamie Zawinski's message threading algorithm: a container per identifier, parents linked from References, and only then a subject-based pass over whatever is still unparented. It is why threading feels similar across unrelated clients.

Two consequences follow.

Threading is per-mailbox. The thread you see is the one your client could reconstruct from the messages you happen to hold. Someone copied in halfway through sees a different shape of the same conversation, and no canonical thread is stored anywhere.

References survives gaps and In-Reply-To does not. If the third message never reached you, its identifier still appears in the fifth's References, so your client attaches to the second instead of giving up. In-Reply-To alone gives recipients one link and no recovery.

Why threads break

A reply that is not a reply. Someone composes from scratch rather than hitting reply. No parent identifier, nothing to attach to.

Dropped or truncated References. Some clients set In-Reply-To alone. Others trim References once it grows long, and a trim that drops the wrong ancestors leaves nothing to attach to.

Forwards. A forward is a fresh message with its own Message-ID, and whether it carries any ancestry depends on the client — many set none. Even when it does, the third party receives identifiers for messages they never held, so the chain dangles.

Mailing lists. List software may prepend a tag to the subject, poisoning the subject fallback, and may add, rewrite or strip identifiers. If it rewrites the Message-ID, the copy that goes out is no longer the copy in the sender's Sent folder, so replies match nothing there.

Subject matching is a repair, not a mechanism

The obvious shortcut is the subject line, and it fails in both directions. It produces false merges — subjects are not unique, so two unrelated messages titled "quick question" become one conversation. And false splits — anyone can rewrite the subject, and a subject-keyed client sees two conversations. It also has to strip reply prefixes that vary by locale and client, tolerate list tags bolted onto the front, and cope with truncation. Every step is a guess.

A well-built client applies subject matching last, only to messages that failed identifier matching outright. The point generalises: any routing rule keyed on a subject line inherits all of this, including that anyone can copy a subject.

What this means for machine-generated correspondence

If a reply must land on one specific conversation — not probably the right one — two things are unavailable to you. The subject line cannot be the key, and you cannot depend on the recipient's client preserving References. Conversation identity has to travel in something you issue and can look up.

RelayLink puts it in the reply address. Each notification carries a Reply-To of the form reply+{token}@ a RelayLink domain, where the token is minted for exactly one package and one recipient — a magic link doing extra duty as a routing key. A plain email reply lands on RelayLink's inbound webhook, the token resolves to its package, and that package's thread is where the reply is written. The subject line names the sender, says "sent you a package", and quotes the topic; it exists for a human to read and routes nothing. The assistant side follows the same discipline — a reply carries the thread's identifier, and a stated recipient contradicting the thread is refused rather than guessed at.

The rough edge is on the reply side. An inbound email arrives with the quoted original attached, so the body must be cut from the quoted tail — a heuristic, and RelayLink treats it as one: such a reply is labelled as typed by the recipient via link or email, not server-authenticated authorship.

None of this repairs threading in your mailbox — RelayLink's notifications are ordinary email once they leave. What the token buys is that the reply's destination does not depend on how your client threads them.

If a message needs to be findable later, attached to the decision it produced, that is a paper-trail problem more than a mail-client one. For the send-and-reply path, see letting your assistant email someone.

Frequently asked questions

What is a Message-ID in an email?
A Message-ID is a globally unique identifier stamped on a message when it is composed, or by the first server to handle it if the client did not add one. It looks like an email address wrapped in angle brackets and it is never meant to be reused. Every threading decision a mail client makes begins by looking a Message-ID up.
Why do my email threads split into separate conversations?
Almost always because the ancestry headers were lost somewhere. A reply composed from scratch carries no parent identifier at all. Some clients set only In-Reply-To, so the chain is one link deep and ends the moment an intermediate message is missing from your mailbox. Mailing list software sometimes rewrites identifiers or edits the subject. Once those references are gone, a client has nothing left to match on but the subject line, which is a guess.
Can email be threaded reliably by subject line?
No. Subjects are not unique, anyone in the conversation can edit them, they collect localised reply prefixes and list tags, and they get truncated. Matching on them merges unrelated conversations that happen to share a title and splits a real one the moment somebody rewrites the subject. It is a repair strategy for messages whose header chain is missing, not the mechanism.