On this page13 sections
Short answer
How do you migrate hundreds of domains to Cloudflare without downtime?
Move DNS first and proxy second. Import every record as DNS-only, change the nameservers, and wait for the zone to go active and for edge certificates to issue. Allow Cloudflare’s addresses at the origin, then switch records to proxied in waves ordered by risk. Rolling back then means switching one hostname to DNS-only, not reversing a nameserver change.
Who this is for: platform, web, and operations leads who own many zones and cannot afford an outage window. This is the staged method we use; our engineers have led staged DNS, SSL, WAF, and bot migrations covering hundreds of domains with tested rollback paths. Zero downtime is the design goal, not a guarantee.
Why do large migrations fail?
They fail on the record nobody knew about, the origin firewall that still blocks the new edge, or a rollback that waits on nameserver caches. Cloudflare’s guidance to minimize downtime uses the same order: unproxied records first, an active edge certificate, Cloudflare’s IP addresses allowed, then proxying.
Two terms matter throughout. A DNS-only record answers with your origin’s IP address, and Cloudflare does not handle the traffic. A proxied record answers with Cloudflare anycast addresses, so traffic passes through Cloudflare’s TLS, cache, and WAF. Only A, AAAA, and CNAME records can be proxied; MX, TXT, and other types are always DNS-only.
The wave model
The wave model orders domains by blast radius. Each wave has a written go/no-go gate and a rollback step. The gates are our published defaults, not Cloudflare recommendations; adjust them to your change process.
| Wave | Scope | Proceed to the next wave when | Rollback step |
|---|---|---|---|
| 0 Pilot | Internal and parked domains | The baseline applies cleanly, with no 52x errors | Set the affected hostnames to DNS-only |
| 1 Low risk | Marketing and static sites | Cache hit ratio and error rates are stable for 48 hours | Same |
| 2 Business | Customer-facing applications | The owner signs off and security events are reviewed | Same, with the owner on the call |
| 3 Critical | Login, payment, APIs | Change window agreed, owners on the call, rollback rehearsed | A rehearsed toggle with a named person who runs it |
Step 1: Take an inventory before anything moves
Export every zone through the current provider’s API and tag each hostname: web, API, mail, verification, or unknown. Unknown is a blocker. Cloudflare’s import scan may miss records, and records added at the old provider after onboarding must also be added in Cloudflare, so freeze DNS changes until the zone is active. Script the imports: Cloudflare documents a 256 KiB limit per zone file and three import requests per minute per user.
Check these per zone:
- Mail. Records used only for email stay DNS-only. Cloudflare does not proxy SMTP on port 25 by default.
- DNSSEC. Cloudflare says to disable DNSSEC at the registrar before changing nameservers, or the domain can become unreachable. Remove the DS record and wait until its TTL expires at the parent zone, commonly 24 to 48 hours;
dig DS example.comshows when it is gone. Changing nameservers earlier makes validating resolvers return SERVFAIL. A multi-signer migration keeps DNSSEC on throughout, if the old provider supports it. - CAA. CAA records must permit the certificate authority Cloudflare uses. If a zone has any CAA record, Cloudflare adds its Universal SSL authorities automatically, but those records do not appear in the dashboard; check with
dig. - Origins that use the client IP. Allow-lists, rate limits, and logs will see Cloudflare addresses once a hostname is proxied; the real client IP arrives in
CF-Connecting-IP.
Step 2: Build one baseline and apply it everywhere
Define the settings once, keep them in Terraform, and import existing configuration with cf-terraforming. Run the generated imports before the first plan; otherwise Terraform tries to create the resources again.
- SSL/TLS mode Full (strict), which needs a valid origin certificate from a public authority or Cloudflare Origin CA. Automatic SSL/TLS is the default for new zones; to pin Full (strict), choose the custom mode.
- Publicly trusted origin certificates for the rollback path. Visitors who reach the origin directly after a DNS-only rollback may see errors with an Origin CA certificate, which only Cloudflare trusts.
- The same minimum TLS version, Always Use HTTPS, and Automatic HTTPS Rewrites on every zone.
- Cache rules for static paths, with the origin’s
Cache-Controlheader as the contract. - Managed WAF rulesets, introduced as described in Step 6.
- HSTS held back until every hostname serves HTTPS and the rollback window has closed. Cloudflare warns that a site can become unreachable for the whole max-age period if HTTPS goes away, and advises against switching records to DNS-only once HSTS is on.
Step 3: Move DNS first, proxy second
Moving DNS and moving traffic are two changes, each with its own check.
- Lower TTLs at the old provider 24 to 48 hours ahead (our default); a resolver may cache a record for its TTL (RFC 1035). This does not shorten DS caching.
- Import every A, AAAA, and CNAME record as DNS-only. Proxying is on by default during onboarding: untick the option to proxy imported records, use the
cf-proxied:falsetag in a zone file, or setproxied: falsein the API. - Change nameservers at the registrar to exactly the two Cloudflare assigns.
- Wait for the zone to show Active, up to 24 hours per Cloudflare, confirmed by email. Re-enable DNSSEC only after this, once the previous nameserver records have expired from caches.
- Confirm edge certificates. Universal SSL is issued after activation, typically within 15 minutes to 24 hours; it is provisioned while records are DNS-only and presented once they are proxied.
- Allow Cloudflare’s published ranges at the origin (
cloudflare.com/ips-v4/,/ips-v6/, or the API). Cloudflare rates an allow-list as moderately secure and open to IP spoofing; block all other addresses only after the rollback window closes. - Switch records to proxied, one wave at a time.
Until step 7, only the server that answers DNS has changed for visitors. That is why this stage can be validated without customer impact.
Step 4: Roll back one hostname, not a whole zone
Once the zone is active, rolling a hostname back is one toggle from proxied to DNS-only. Proxied records use an Auto TTL of 300 seconds, so resolvers typically pick up the change in about five minutes, though local caches can take longer. The rollback works while HSTS is off, the origin has a publicly trusted certificate, and the origin still accepts direct traffic; the origin IP is visible while the hostname is DNS-only. A nameserver rollback waits on registry and resolver caches that you do not control; we do not rely on it.
The migration cutover checklist
Print it per wave. Every line is pass or fail.
| Phase | Check |
|---|---|
| Before cutover | Inventory complete; no unknown hostnames; DNS changes frozen at the old provider |
| DNSSEC state recorded; DS removed and its TTL expired, or a multi-signer plan agreed | |
| CAA records permit Cloudflare’s certificate authorities | |
Baseline applied; terraform plan shows no unexpected change |
|
| Rollback hostnames have publicly trusted origin certificates; HSTS off | |
| TTLs lowered; registrar access and an owner per hostname confirmed | |
| Cutover | Records imported as DNS-only; nameservers changed; zone Active |
| Edge certificate active for every hostname, including deeper names | |
| Origin allows Cloudflare ranges; hostnames in this wave switched to proxied | |
| Verification | Site and API checks pass from outside your network; mail flow tested |
| Edge and origin status codes, cache hit ratio, and security events reviewed | |
| Rollback | Toggle owner named; trigger conditions written; decision time-boxed |
Step 5: Watch the right signals after each wave
After each wave we compare edge and origin status codes, with 520 to 526 counted separately, cache hit ratio for cacheable paths, and security events by rule. The data comes from the GraphQL Analytics API at https://api.cloudflare.com/client/v4/graphql. Its httpRequestsAdaptiveGroups dataset is available on all plans with at least 31 days of data, and Cloudflare documents edgeResponseStatus and originResponseStatus. Confirm the exact fields by schema introspection, and pace the queries: 300 per five minutes per user, up to 10 zones per query.
Step 6: Keep security changes separate
Do not move DNS and tighten security in the same change. Cloudflare documents the Log action as Enterprise-only; custom rules on Free, Pro, and Business support every other action. On those plans, filter the expected traffic in Security Analytics and create the rule from those filters; our practice is then to go live on a low-risk subset first. The WAF rollout article has the full runbook.
What this article has not tested
- A partial (CNAME) setup at this scale, and the multi-signer DNSSEC path.
- Cloudflare’s Migration Hub, a migration services team with a free assessment, compared with this method.
- The 48-hour gate and the TTL lead time are our defaults, not Cloudflare figures.
FAQ
Does email keep working during the move?
Yes, if mail records stay DNS-only. MX and TXT records cannot be proxied, records used only for email should stay DNS-only, and Cloudflare does not proxy SMTP on port 25 by default. Import mail records exactly, compare SPF, DKIM, and DMARC with the old zone, and send test messages after the nameserver change.
What do I do about DNSSEC?
Disable it at the registrar first. Remove the DS record, wait until its TTL expires at the parent zone, commonly 24 to 48 hours, and only then change nameservers; otherwise validating resolvers return SERVFAIL. After the zone is active and the old nameserver records have expired, enable DNSSEC in Cloudflare and add the new DS record.
How long does a nameserver change take?
Cloudflare says to allow up to 24 hours for the registrar to update the nameservers; the zone then shows Active and Cloudflare sends an email. Universal SSL follows, typically within 15 minutes to 24 hours of activation. Plan the cutover so that nothing depends on the exact minute, and keep proxy changes in a later step.
Do certificates cover every subdomain?
Not automatically. On a full setup, Universal SSL covers the root domain and first-level subdomains. Deeper names need Total TLS, which requires Advanced Certificate Manager, an advanced certificate, or a custom certificate. Partial setups, on Business and Enterprise, issue a certificate per proxied hostname. Check the inventory for deeper names before proxying them.
Does the DNS-only rollback still work after HSTS or an origin lockdown?
Not reliably. Cloudflare advises against switching records from proxied to DNS-only once HSTS is on, browsers do not trust Origin CA certificates, and an origin that blocks everything except Cloudflare cannot serve direct traffic. Hold HSTS and the lockdown until the wave’s rollback window has closed, and use publicly trusted origin certificates.
Sources
Checked against vendor documentation on How the articles are checked
- Minimize downtime
- Full setup
- Proxy status
- Proxy status use cases (email, source IP)
- Import and export DNS records
- DNSSEC
- CAA records
- Universal SSL
- Enable Universal SSL
- SSL/TLS encryption modes
- Encrypt all traffic (Automatic SSL/TLS)
- Origin CA certificates
- HTTP Strict Transport Security
- Protect your origin server
- Cloudflare IP ranges
- GraphQL Analytics API
- GraphQL Analytics API limits
- Origin Analytics
- Rules language actions
- Security Analytics
- Import Cloudflare resources (cf-terraforming)
- RFC 1035, sections 3.2.1 and 4.1.3 (TTL)
- Migrating hundreds of domains to Cloudflare without downtime (author’s original write-up)