Root Domain or Docs Subdomain: Where Should llms.txt Live?
Most companies do not have one website — they have a marketing host, a docs host, a status host and a help
centre, often on four different subdomains. A single llms.txt at the root covers only the first.
We fetched 30 llms.txt URLs on October 24, 2026 — eight brand pairs plus 12 single hosts — to see
how the largest sites actually handle it. Nineteen serve a real file, 10 answer 404, and one answers 200 with
a 404 page inside the body.
What the 30 Requests Returned
Every request was a normal desktop user agent, redirects followed, and each body parsed for its H1, Markdown
links, .md twins and H2 count. Fourteen of the 19 real files arrive as text/plain,
five as text/markdown — and all five Markdown responses come from a documentation or help host.
| Host | Status | Type | Bytes | Links | .md |
|---|---|---|---|---|---|
| stripe.com | 200 | text/plain | 69,923 | 306 | 24 |
| docs.stripe.com | 200 | text/markdown | 97,577 | 497 | 491 |
| github.com | 200 | text/plain | 28,658 | 117 | 0 |
| docs.github.com | 200 | text/markdown | 28,642 | 117 | 0 |
| www.cloudflare.com | 200 | text/plain | 17,173 | 90 | 82 |
| developers.cloudflare.com | 200 | text/plain | 16,787 | 112 | 0 |
| docs.aws.amazon.com | 200 | text/plain | 418,948 | 1,299 | 1,294 |
| aws.amazon.com | 404 | text/html | 302,410 | — | — |
| help.shopify.com | 200 | text/markdown | 4,712 | 0 | 0 |
| shopify.dev | 404 | text/html | 80,728 | — | — |
| docs.python.org | 404 | text/html | 146 | — | — |
| cloud.google.com | 200 | text/html | 41,682 | — | — |
Of the eight brand pairs, three serve a real file on both hosts (Stripe, GitHub, Cloudflare), two serve only
on the documentation side (AWS, Shopify's help centre) and three serve on neither (Microsoft, Mozilla,
Python). The pair that publishes only the docs file is the one that proves the point: AWS's
418,948-byte index lives at docs.aws.amazon.com while aws.amazon.com/llms.txt spends
302,410 bytes of HTML saying 404. An agent that starts at the marketing host never learns the docs file
exists.
Delegation: The Stripe Pattern
Stripe publishes two different files and the root one points at the other. Its
## Documentation section opens with a single link to the docs host's file, followed by four
.md twins:
## Documentation
- [Stripe Documentation](https://docs.stripe.com/llms.txt): Explore our guides and examples to integrate Stripe.
- [API Reference](https://docs.stripe.com/api.md): Complete reference for all Stripe API endpoints.
- [Testing](https://docs.stripe.com/testing.md): Simulate payments and test your integration.
That one line is the whole cross-host strategy. The root file (69,923 bytes, 306 links, H1
# Stripe) describes the marketing site; the docs file (97,577 bytes, 497 links, 491
.md twins, H1 # Stripe Documentation) describes the reference. An agent that lands on
either one can reach the other, and neither has to be rewritten when the other changes. Cloudflare does the
same thing the same way — its root file opens by naming the other host ("For technical documentation, see
developers.cloudflare.com") and later links it — with one gap: the link points at the HTML page, not at
developers.cloudflare.com/llms.txt, so the agent has to discover the file from the convention
rather than from the map.
Duplication: The GitHub 16-Byte Drift
GitHub takes the other route and serves both. The two files are nearly the same length — 28,658 and 28,642
bytes, a 16-byte difference — and both contain 117 links. They are not the same document. The H1 differs
(# GitHub versus # GitHub Docs), the H2 count differs (12 versus 14), and the docs
host carries a full ## Get started section that the root file does not have, complete with its
own summary blockquote. Several entries also diverge: the root file links “About cloud agent” where the docs
file links “Copilot on GitHub.com”, the docs file adds an “Individual plans” entry and drops “Chat in IDE”,
and one MCP walkthrough points at a different path on each host.
That is what two generators fed by two manifests look like after a few months. Nothing is broken — every link resolves — but the two maps disagree about the product. If you duplicate, generate both files from one route list so the shared sections cannot drift; the split should be a filter, not a second editorial pass.
The .md Twins Landed on the Wrong Host
Cloudflare's root file lists 82 Markdown twins out of 90 links. Its docs host — where the reference pages
actually live — lists 112 links and zero .md twins. So the host an agent reaches when it wants
technical content hands over HTML URLs, while the marketing host hands over clean Markdown. The developers
file compensates with a deeper tier: each product links its own scoped file
(/argo-smart-routing/llms.txt, /cache/llms.txt), which is the right instinct —
per-path splitting is exactly what the spec's path-scoping rule is for, and it is the same mechanic behind
per-version files and
per-language files.
The rule that follows: put the Markdown twins on the host that serves the pages, not on the host that sells
the product. A .md twin is worth most where the content is deepest, and link hygiene on a
multi-host estate means checking each file's links against the host that file lives on.
Redirects on the Root Path: Two Ways They Fail
Shopify's help centre redirects /llms.txt to /agents.md and serves 4,712 bytes of
text/markdown. The body is a procedure rather than an index — it has four H2 sections and zero
links, and it spends its words explaining that every public English page is available as Markdown by
appending .md or by sending Accept: text/markdown. A redirect to a live document
is fine; what it must not do is redirect to nothing. shopify.dev/llms.txt redirects to
/llms.md and lands on an 80,728-byte HTML 404 — two requests, no file.
The second failure is a locale redirect on the root path. learn.microsoft.com/llms.txt 301s to
/en-us/llms.txt and www.mozilla.org/llms.txt 301s to /en-US/llms.txt;
both land on 404. If your edge stamps a locale onto every root path, exempt this one: the path is defined at
the host root and has no language variant.
Four Rules for a Multi-Host Estate
- One file per host that owns content. Path scoping means the root file cannot describe another subdomain. Publishing at the docs host is not optional if the docs host is where the pages are.
- Delegate from the root. One link to
https://docs.example.com/llms.txtin the root file's docs section — the Stripe pattern — costs a line and makes the second file discoverable. The channels that matter are the ones in our discovery guide. - If you duplicate, share the manifest. A 16-byte size delta with divergent sections (GitHub) is the signature of two hand-maintained sources.
- Watch the byte budget per host. Splitting by host is not a diet: the largest files in this set are single-host monsters — Twilio at 2,357,852 bytes, AWS at 418,948, Snyk at 307,088. Split by depth as well as by host — see size limits and token budgets.
The Five-Command Multi-Host Check
# 1. every host that owns content, in one pass
for h in example.com docs.example.com help.example.com; do
curl -sS -o /dev/null -w "$h %{http_code} %{content_type} %{size_download} %{num_redirects}\n" \
"https://$h/llms.txt"
done
# 2. where did the redirect actually land?
curl -sSL -o /dev/null -w "%{url_effective}\n" https://docs.example.com/llms.txt
# 3. which file does the root name?
curl -s https://example.com/llms.txt | grep -oE 'https://[a-z.]*example\.com/llms\.txt'
# 4. .md twins per host — the number should be highest where the pages are
for h in example.com docs.example.com; do
echo -n "$h "; curl -s "https://$h/llms.txt" | grep -c '\.md)'
done
# 5. the 200-with-HTML trap: a SPA catch-all answers the path with a page
curl -s https://docs.example.com/llms.txt | head -1
Command 5 is the one that separates a real estate from a green dashboard.
cloud.google.com/llms.txt answers 200, text/html, 41,682 bytes — with
<title>404. Page Not Found</title> inside it. A status-code monitor reports a pass
for a host that publishes nothing. Paste the body into the
checker and you get the real answer in one step;
build both hosts' files from the same sitemap with the
generator and the drift problem never starts.