A migration done in the wrong order means downtime or lost orders. Done in this order, visitors never see a gap. The trick is to have the new server fully working before DNS points at it.
1. Lower your DNS TTL first, days before
This is the step everyone skips and then regrets. TTL is how long the internet caches your DNS record. If it is set to 24 hours, some visitors keep hitting the old server for a day after you switch.
At your DNS provider, set the TTL on your A and AAAA records to 300 seconds. Do it at least 24 hours before the migration, so the old long TTL has expired everywhere by the time you switch.
2. Build the new server
Install the same stack: web server, PHP or your runtime, database. Match major versions with the old server. Moving hosts and upgrading PHP at the same time turns one problem into two.
Set up the firewall now, before any data is on it. Our firewall guide covers it.
3. Copy the files
Run this from the old server. rsync copies only what changed, so you can run it more than once and the second run takes seconds.
$ rsync -avz --progress /var/www/ [email protected]:/var/www/
-a keeps permissions, ownership, and timestamps. Copying with scp instead loses those and breaks file uploads on the new server.
4. Copy the database
$ mysqldump -u root -p --single-transaction --routines --triggers mydb > /root/mydb.sql $ rsync -avz /root/mydb.sql [email protected]:/root/
--single-transaction takes a consistent dump without locking the tables, so the old site stays up while it runs.
On the new server:
$ mysql -u root -p -e "CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" $ mysql -u root -p mydb < /root/mydb.sql
Create the same database user with the same name and password the application config expects, so you do not have to edit application files.
5. Test before switching anything
Do not point DNS yet. Instead, tell your own computer that the domain lives at the new server, by editing your hosts file. On Linux and macOS it is /etc/hosts; on Windows it is C:\Windows\System32\drivers\etc\hosts.
203.0.113.10 example.com www.example.com
Now your browser goes to the new server while the rest of the world still goes to the old one. Click through the site properly: log in, submit a form, upload a file, check pages that use the database. Fix what is broken. Nobody else is affected.
Remove that line from your hosts file when you are done testing.
Certificates do not copy over cleanly
Do not copy /etc/letsencrypt from the old server. Issue a fresh certificate on the new one after DNS points at it. Until then, test over HTTP or accept the browser warning; a certificate cannot be issued for a domain that still resolves elsewhere.
6. Do the final sync and switch
Pick a quiet hour. Then:
- Put the old site in maintenance mode, or accept that changes in the next few minutes will be lost.
- Run the
rsyncand the database dump again. The second run is fast because only recent changes move. - Change the A and AAAA records at your DNS provider to the new server's addresses.
- Watch both servers' access logs. Traffic drains from the old one and appears on the new one within minutes, because you lowered the TTL in step 1.
$ sudo tail -f /var/log/nginx/access.log7. After the switch
Issue the certificate now that DNS resolves to the new server:
$ sudo certbot --nginx -d example.com -d www.example.comThen raise the TTL back to 3600 or higher, and keep the old server running for a week. If something turns up missing, the data is still there.
Quick reference
| Step | When | Command or action |
|---|---|---|
| Lower TTL to 300 | 24h before | DNS provider |
| Copy files | Anytime | rsync -avz /var/www/ root@NEW:/var/www/ |
| Copy database | Anytime | mysqldump --single-transaction |
| Test privately | Before switch | Edit your hosts file |
| Final sync | Switch hour | Repeat rsync and dump |
| Switch | Switch hour | Change A and AAAA records |
| Certificate | After switch | certbot --nginx |
Where to go next
Keep the old server for a week, then cancel it. Set up backups on the new server before you do, because the moment you cancel the old one, the new server is the only copy.