Downtime during a move usually comes from one of three things: switching DNS before the new server is ready, a long TTL that strands visitors on a server you have already shut down, or data written to the old server after the copy was taken. A zero-downtime move avoids all three.
The principle
Both servers run a working copy of the site at the same time. DNS decides which one each visitor reaches. Because both work, it does not matter which one they get while the change spreads.
Steps
- Lower the TTL to 300 seconds a day or more ahead.
- Build and test the new server completely through your hosts file, while the old one keeps serving everyone. See the checklist.
- Freeze changes, or plan for them. For a brochure site, a short content freeze is enough. For a shop or forum, put the old site in maintenance mode for the final sync, or accept that you will copy late orders across by hand.
- Do a final data sync so the new server has the latest database and uploads.
rsynconly copies what changed, so it is quick:
rsync -avz olduser@old.server.ip:/var/www/example.com/public/wp-content/uploads/ /var/www/example.com/public/wp-content/uploads/
- Switch DNS. With a 300-second TTL, most traffic moves within minutes.
- Leave the old server running for at least 72 hours. Some resolvers ignore low TTLs.
Sites where data changes constantly
A shop, forum or booking site takes new orders and posts every minute. While DNS is changing, some visitors write to the old server and some to the new, and the two databases drift apart. Choose one approach in advance:
| Approach | Downtime | Effort |
|---|---|---|
| Maintenance mode on the old site during the final sync and switch | 5 to 15 minutes for writes | Low |
| Point the old site’s database connection at the new server’s database, so both servers share one database | None | Medium: the new database must accept remote connections securely |
| Put a reverse proxy on the old server that forwards everything to the new one | None | Medium |
| Database replication from old to new, then promote the new one | None | High |
For most small shops, a short maintenance window at a quiet hour is the right trade-off. Announce it, take the final database copy, switch DNS, and lift maintenance mode on the new server.
The proxy approach works well: once the new server is live, configure the old server’s Nginx to pass every request to the new server’s IP. Visitors still reaching the old server through stale DNS are served by the new one, so all writes land in one place:
location / {
proxy_pass https://203.0.113.20;
proxy_set_header Host $host;
proxy_ssl_server_name on;
proxy_ssl_name $host;
}
Behind a CDN, there is no propagation
If your site is behind Cloudflare or another proxy CDN, visitors’ DNS points at the CDN, not your server. Changing the origin IP in the CDN’s dashboard takes effect within seconds, everywhere, with no TTL wait. That makes a CDN worth setting up before a move even if you do not need it afterwards. See what a CDN is.
Certificates without a gap
Let’s Encrypt’s normal HTTP check needs DNS to already point at the new server, which leaves a few minutes without a valid certificate. Two ways to avoid that:
- Copy the existing certificate from the old server to the new one before switching, then renew normally afterwards.
- Use a DNS challenge (
certbot --preferred-challenges dns), which proves ownership through a TXT record and works before the switch.
How to tell the move is finished
Watch the old server’s access log. When it only shows bots and stragglers for a full day, the move is complete.
sudo tail -f /var/log/nginx/access.log
Rolling back
If something goes wrong after the switch, change the A record back to the old IP. With a 300-second TTL, most visitors are back on the old server in five minutes. Anything written to the new server in the meantime, such as orders or comments, needs copying back, which is one more reason for a short maintenance window on busy sites.
Related
Something out of date? Software changes. If a step no longer works, tell us and we will check it and update the page.

