How to change hosts without downtime

Run the old and new servers side by side, switch DNS when the new one is proven, and keep the old one answering until the world has caught up.

1–2 minutes
Dense bundle of patch cables in a network rack

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

  1. Lower the TTL to 300 seconds a day or more ahead.
  2. Build and test the new server completely through your hosts file, while the old one keeps serving everyone. See the checklist.
  3. 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.
  4. Do a final data sync so the new server has the latest database and uploads. rsync only 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/
  1. Switch DNS. With a 300-second TTL, most traffic moves within minutes.
  2. Leave the old server running for at least 72 hours. Some resolvers ignore low TTLs.

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

Something out of date? Software changes. If a step no longer works, tell us and we will check it and update the page.