Migrating a Website: Moving Files, Database, and Domain Without Downtime
Move files with rsync, migrate the database with mysqldump, verify before flipping DNS, and lower your TTL ahead of time for a near-zero-downtime cutover.
The scariest part of moving a website from an old server to a new VPS is that one moment when the site goes dark. But if you follow the right order—stand up the new site first, verify it, and only then switch DNS—you can make the cutover almost seamless. Here's a copy-and-paste-friendly workflow.
1. Lower Your DNS TTL Ahead of Time
This is the step everyone forgets, yet it matters most. Do it 1–2 days before the move. In your domain's DNS panel, change the TTL on your main records (such as @ and www) from the usual 3600 seconds down to 300 (5 minutes) or even 60. TTL controls how long DNS caches around the world hold the old answer. Lowering it early means that when you actually flip the record, the old value expires fast—and so does any rollback. Bump the TTL back up a few days after everything is stable.
2. Package and Transfer Site Files
On the old server, archive the site directory, preserving permissions and symlinks:
cd /var/www
tar --numeric-owner -czpf site.tar.gz html
Copy it to the new box (pull it there, or send it directly with rsync):
rsync -avz -e ssh /var/www/html/ user@NEW_IP:/var/www/html/
rsync does incremental syncs, so you can run it again later to move only what changed—shrinking the final "last sync" window to almost nothing.
3. Export and Import the Database
Export on the old server (MySQL/MariaDB shown here):
mysqldump -u root -p --single-transaction --routines --triggers mydb > mydb.sql
--single-transaction gives you a consistent snapshot without locking the tables. After copying mydb.sql to the new box, import it:
mysql -u root -p -e "CREATE DATABASE mydb CHARACTER SET utf8mb4;"
mysql -u root -p mydb < mydb.sql
Don't forget to recreate the application's database user and grant it the same privileges it had on the old site.
4. Point the Config at the New Database
Edit your site's config file (for example wp-config.php for WordPress, or .env for Laravel) and update the database host, name, user, and password to the new values. If the database and the site live on the same machine, set DBHOST to 127.0.0.1.
5. Verify Before Touching DNS
Don't change DNS yet. First, force the domain to resolve to the new server on your own computer using hosts, so you can test in isolation:
# Edit /etc/hosts on Linux/macOS; on Windows it's C:\Windows\System32\drivers\etc\hosts
203.0.113.20 example.com www.example.com
Then open the domain in your browser and check everything: home page, login, images, admin panel, payment callbacks. Once it all works, remove that line.
6. Flip DNS and Wrap Up
In your DNS panel, point the A record (and AAAA if you use IPv6) at the new server's IP. Because the TTL is already down to 5 minutes, the change propagates worldwide within a few minutes. Right after the switch, run one final incremental rsync and a database top-up to capture any data created during the cutover window. Confirm the change with dig example.com.
Watch the new site's access and error logs. Once traffic has fully shifted and the old server sees no more real requests, keep the old box around for a few days as a rollback safety net—then, and only then, decommission it.
Summary
Zero-downtime migration really comes down to two habits: lower the TTL in advance and verify via hosts before flipping DNS. Follow the sequence—transfer files → migrate the database → update config → verify with hosts → switch DNS → sync the delta → retire the old site—and pair it with incremental rsync and mysqldump --single-transaction. Your users will barely notice a thing.