Guide
DNS and edge topology for crawler routing
The zone-level decisions a crawler-facing rollout depends on: which records are proxied, what TTL bounds your rollback window, how forward-confirmed reverse DNS actually verifies a bot, and why an exposed origin defeats the WAF rules above it.
Introduction
Most pre-rendering documentation starts at the middleware. By then the interesting decisions have already been made: the crawler resolved a hostname, got an address, and connected to whatever was listening. If that address was your origin rather than an edge, every rule you wrote afterwards — bot routing, WAF allowlists, cache policy — governs only the traffic that chose to arrive politely.
This guide covers the layer underneath. It is deliberately narrow: four decisions, each with a command that tells you the current state rather than the intended one. None of it is exotic, and all of it is the kind of thing teams discover during an incident instead of during planning.
Read it alongside the WAF over-blocking guide, which covers the firewall rules that sit one layer up, and the pre-launch checklist, which folds these checks into a go-live sequence.
How to: DNS & edge topology
- 1
Record what your zone answers today, not what the dashboard says
Dashboards show intent. Resolvers show reality, and the two drift after every hurried change. Query the public answer for each hostname that serves indexable content, and record the TTL alongside the value — the TTL is what will bound every change you make later.
zone-snapshot.shbashfor host in example.com www.example.com shop.example.com; do# value + TTL, straight from a public resolverdig @1.1.1.1 +noall +answer "$host" A | awk '{print $1, "TTL="$2, $4, $5}'done# Who is authoritative, and is the zone signed?dig +short NS example.comdig +short DS example.com # empty = DNSSEC not enabled at the registrar - 2
Decide which hostnames resolve to the edge and which do not
A proxied record answers with an edge address and keeps the origin address as a private property of that record. An unproxied record publishes your server. The choice is per hostname, and it is worth being explicit: mail, SSH, staging, and API hosts frequently should not be proxied, while every hostname serving indexable HTML almost always should. Cloudflare exposes this as the orange-cloud proxy state; Bridge DNS — operated by the same team as this site — exposes it as a per-record toggle with origin port, protocol, and `Host` header set next to the record.
- 3
Set TTLs to match the rollback window you actually want
TTL is the only lever you have over how long a mistake survives. A record at 3600 seconds means resolvers may serve the old answer for an hour after you fix it, and no provider can purge public resolver caches. Publish a low TTL *before* a planned change, not during it: resolvers only learn the new TTL when their cached copy expires, so the short value has to be live for longer than the old TTL to take effect everywhere.
ttl-plan.txtbashT-48h Set TTL to 300 on every record the change will touch.T-24h Verify propagation of the *TTL itself*, not just the value:dig @8.8.8.8 +noall +answer www.example.com | awk '{print $2}'dig @1.1.1.1 +noall +answer www.example.com | awk '{print $2}'Both should print 300 or less before you proceed.T-0 Make the change. Rollback window is now ~5 minutes, not ~1 hour.T+24h Once the new value is stable, restore the normal TTL. - 4
Verify the crawlers you allow, using both halves of the reverse check
Allowlisting a User-Agent string allows anyone who can type it. Forward-confirmed reverse DNS is the check that actually holds: resolve the request IP to a `PTR` name, confirm the name belongs to a domain the crawler publishes, then resolve that name back and confirm it returns the original IP. Cache the verdict per IP — the check costs two round trips, and re-running it on every request puts a DNS lookup in your hot path.
verify-crawler.shbashIP="66.249.66.1"NAME=$(dig +short -x "$IP" | sed 's/\.$//')case "$NAME" in*.googlebot.com|*.google.com|*.search.msn.com) ;;*) echo "reject: PTR '$NAME' not a published crawler domain"; exit 1 ;;esac# Forward-confirm: this is the half that makes the check meaningfuldig +short "$NAME" | grep -qx "$IP" \&& echo "verified: $IP" \|| echo "reject: forward lookup does not match $IP" - 5
Confirm the origin refuses traffic that skipped the edge
Proxying the record hides the origin address from public answers; it does not stop anyone who already knows it. Historical DNS archives, TLS certificate transparency logs, old mail headers, and a misconfigured subdomain all leak origin addresses routinely. Close the loop at the origin firewall: accept inbound 80/443 only from your edge provider's published ranges, and reject everything else.
origin-exposure.shbash# 1. Public answer must be an edge addressdig +short www.example.com# 2. From a host outside your network, force the origin IP with the real Hostcurl -sS -o /dev/null -w '%{http_code}\n' \--resolve www.example.com:443:198.51.100.25 \https://www.example.com/# 200 here means the WAF, the bot rules, and the rate limits# above it are all optional from an attacker's point of view.# Expect a connection timeout or a 403 from the origin firewall. - 6
Write the rollback path down before you need it
Every rollout has a slowest reversible layer, and that layer defines your incident response time. A proxy upstream or a route flag reverts in seconds. A record change reverts in one TTL. A nameserver change reverts on the registrar's and the TLD's schedule, which is not yours. Decide which layer your rollout touches, write the revert command in the runbook, and if the answer is 'nameservers', schedule the change for a week you can afford to watch.
How fast each layer reverts
Rollback speed by the layer a change touches. The slowest layer you modified sets your real recovery time, regardless of how fast the others are.
Layer changed | Revert mechanism | Realistic window |
|---|---|---|
| Proxy upstream / route flag | Config push | Seconds |
| Edge cache contents | Purge API | Seconds to minutes |
| Proxied A/AAAA target | Edge re-points; public answer unchanged | Seconds at the edge |
| Unproxied record value | Edit record, wait out caches | Up to one full TTL |
| Record TTL itself | Edit, then wait out the previous TTL | Up to the old TTL |
| Nameserver delegation | Registrar change, then TLD + resolver caches | Hours to days |
An exposed origin makes the layers above it optional
This is the failure that survives a clean audit of everything else. The WAF rules are correct, the bot allowlist is correct, the rate limits are correct — and the origin still answers on its own address to anyone who sends the right `Host` header. Scrapers do this as a matter of routine because it is cheaper than solving challenges, and the traffic never appears in the firewall event log, so the dashboards stay green while the origin absorbs the load.
Proxying the record is the first half of the fix and the only half most teams do. The second half is at the origin: restrict inbound 80/443 to your edge provider's published ranges. Until that is in place, hiding the address is obscurity rather than control — and addresses leak through certificate transparency logs, historical DNS archives, and any subdomain that was never proxied in the first place.
The check is two commands and belongs in the pre-launch checklist rather than in a quarterly review.
What to ask a DNS provider when the zone carries a crawler path
Most zone requirements are boring until a rollout depends on them. Five are worth checking before you need them: per-record proxying rather than an all-or-nothing zone setting; per-record TTL you can lower and restore without a support ticket; origin port and `Host` header control, which matters the moment one origin serves several hostnames; DNSSEC signing if your registrar supports delegation; and whether records can be managed through an API or IaC provider at all.
That last one splits providers sharply, and the trade is real in both directions. Bridge DNS, from the same team as this site, is explicit that it offers no public DNS API — positioning zone import and a reviewable diff against live DNS instead, on the argument that an absent API is an absent attack surface. For a handful of domains that is defensible. For an agency or platform team pushing record changes across dozens of zones from a pipeline, it is a blocker, and Route 53, Cloudflare, or NS1 fit that shape better. Score it against how your team actually operates rather than against the vendor's framing.
Whichever provider runs the zone, verify the behaviour rather than the marketing: change a record, then poll two public resolvers until the new value appears, and record how long it took. That number is your real propagation figure, and it is the one to put in the runbook.
What this layer cannot do for you
DNS decides where a request lands. It has no opinion about what is served once it gets there. A perfectly configured zone in front of a client-rendered SPA still hands crawlers an empty shell — the routing is correct and the payload is empty, which is why this guide is a supplement to the rendering decision rather than a substitute for it.
It also does not do geographic or latency-based routing on every provider, and it never decides which crawler gets which response. That classification happens above, at the edge or in middleware, and is covered in bot detection and offloading bot visits.
Finally, DNS changes are not a deployment mechanism. Anything you can express as a proxy upstream, a route flag, or a cache purge should be expressed that way, precisely because those revert in seconds and a record does not.
Questions engineers ask about this guide
At least as long as the current TTL, and 24 hours is a safe default for the common 3600-second setting. Resolvers only pick up the new, shorter TTL when their existing cached copy expires, so publishing 300 seconds an hour before a change leaves plenty of resolvers still holding the old one-hour value.
It stops opportunistic scanning and makes targeted work harder. It does not stop anyone who already has the address, and addresses leak through certificate transparency logs, historical DNS records, and unproxied subdomains. Pair record proxying with an origin firewall that only accepts your edge provider's ranges — that is the part that enforces it.
Not if the new provider already serves the same records before you switch. Import the zone, verify it answers correctly by querying the new nameservers directly, then change the delegation. Both providers keep answering while resolvers migrate. If DNSSEC is enabled, disable delegation at the registrar before moving, or validating resolvers will fail closed.
No. User-Agent strings are trivially spoofed, and treating them as identity means anyone can request your prerendered path or your allowlisted rules. Forward-confirmed reverse DNS — PTR lookup, domain check, then a forward lookup that must return the original IP — is the verification Google and Bing both document.
Usually not. A separate hostname splits signals, needs its own canonical discipline, and creates a surface where crawlers and users can receive genuinely different URLs. Route by request attributes on the same hostname instead, and keep the difference to the response rather than the address.
Related guides and deep dives
WAF over-blocking fix
The firewall layer directly above this one, provider by provider.
Pre-launch checklist
Where these checks fit in a go-live sequence.
Bot detection and offloading
Classifying crawler traffic once it reaches the edge.
Guide — cache headers
Cache-Control and Vary once routing is settled.
Guide — large sites (100k+ pages)
Where hostname and sharding decisions start to matter.
Compare — vs Cloudflare
Build-vs-buy at the edge layer these records point to.
Editorial trust
Written by ostr.io engineering team · Engineering Team. We build and run pre-rendering infrastructure for more than 200 engineering teams, which is where the numbers and code samples on this page come from.
Last updated . Editorial scope and review policy: About prerender.info.