Website Migration Guide (Zero Downtime, Step by Step)
Last updated: 23 September 2026
Moving a website to another server or hosting company, when done in the right order, completes with no visitor seeing any downtime. The secret is simple: do not change DNS until the new server is fully prepared and tested. This guide walks through the process step by step, along with the TTL strategy.
The general idea
During the migration both servers host the same site for a while. Visitors move gradually from the old server to the new one according to their DNS caches. The risk of downtime is in three places: missing files/data, a configuration that does not work on the new server, and data written during the DNS switch being split between the two. All are solved by planning.
1. Preparation and inventory
- Site type and stack: PHP version, database (MySQL/MariaDB/PostgreSQL), required extensions.
- List of domains and subdomains.
- A full dump of the current DNS records — especially MX (email!), TXT (SPF/DKIM/verification), CNAMEs.
- SSL: to be re-obtained on the new server with Let's Encrypt.
- Cron jobs, background workers, environment variables (
.env). - Where is the email? If the domain's email is also on this server, include it in the migration plan.
2. Lower the TTL (24–48 hours before the migration)
The TTL of DNS records determines how long caches keep them. Lower it before the switch so the change propagates quickly:
yoursite.com. A 300 203.0.113.10 ; TTL 3600 → 300 (5 min)
This change itself propagates in the time of the old TTL — which is why it is done a day or two in advance.
3. Set up the new server
- Install the web server + PHP + database (LEMP setup).
- Provide the same PHP version and extensions — a version mismatch is the most common migration error.
- Define the server block / vhost for the domain.
4. Transfer the files
# Archive on the old server
tar czf site.tar.gz -C /var/www/yoursite.com .
# Copy to the new server (from the new server)
rsync -avz old-server:/tmp/site.tar.gz /tmp/
# or directly:
rsync -avz --progress old-server:/var/www/yoursite.com/ /var/www/yoursite.com/
Fix file ownership: sudo chown -R www-data:www-data /var/www/yoursite.com
5. Transfer the database
# On the old server
mysqldump -u root -p --single-transaction --routines app_db > app_db.sql
# On the new server
mysql -u root -p -e "CREATE DATABASE app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u root -p app_db < app_db.sql
In the application config file (.env, wp-config.php, etc.), enter the new database user/password.
6. Test WITHOUT changing DNS
This step is the heart of a zero-downtime migration. Add a temporary entry to your computer's hosts file to point the site to the new server just for you:
# Linux/Mac: /etc/hosts — Windows: C:\Windows\System32\drivers\etc\hosts
203.0.113.10 yoursite.com www.yoursite.com
Now yoursite.com goes to the new server in your browser. Checklist:
- Do the home page, inner pages and images load?
- Do login, form submission and the payment flow work?
- Does the admin panel open?
- Are the logs clean? (
tail -fNginx + application log)
When testing is done, remove the hosts line.
7. Obtain SSL on the new server
Because DNS still points to the old server, HTTP-01 validation may not work. Options:
- Obtain it now with DNS-01 validation (by adding a TXT record).
- Or run
certbot --nginxright after the DNS switch (if a few minutes of an HTTP window is acceptable).
8. Freeze writes and do a final sync
If the site produces user content (comments, orders, memberships):
- Announce a short maintenance window or put the site into "read-only" mode.
- Do a final differential sync of the database and the
uploadsdirectory. - Change DNS.
For most sites other than high-traffic/transactional ones, a 10-minute window at midnight is enough.
9. Change DNS
yoursite.com. A 300 203.0.113.20 ; new IP
www.yoursite.com. A 300 203.0.113.20
Because the TTL is 300, most visitors move to the new server in 5–15 minutes; full propagation can take a few hours.
10. After the switch
- Keep both servers running for at least 48–72 hours (for visitors with late propagation).
- Watch the old server logs — you can shut it down once traffic drops to zero.
- Raise the TTL back to normal (3600 or higher).
- Check Analytics, Search Console, uptime monitor.
- Take a full backup of the new server before deleting data on the old one.
WordPress-specific notes
- If the domain stays the same, no URL change is needed; just update the database details in
wp-config.php. - If the domain changes:
wp search-replace 'old.com' 'new.com' --all-tables(WP-CLI) — it handles serialised data correctly, do not do a manual SQLUPDATE. - Plugins like "Duplicator" and "All-in-One WP Migration" automate most of these steps for small sites.