Start typing to search across invoices, services, domains, tickets, and more...
When you change data centers, upgrade your configuration or move from another provider, the biggest worries are data loss and prolonged downtime. This guide walks through a migration workflow proven in practice: incremental file sync with rsync, database migration with mysqldump, and lowering DNS TTL in advance for a smooth cutover. For most websites, this keeps downtime to just a few minutes.
--single-transaction option exports a consistent snapshot without locking tables.rsync is installedInstall rsync:
# Debian / Ubuntu
apt install -y rsync
# RHEL / Rocky / AlmaLinux
dnf install -y rsync
| Item | Details |
|---|---|
| Full backup | Take a full backup or snapshot of the source server before migrating |
| Disk space | Use df -h and du -sh to confirm the target disk has enough space |
| Software versions | Compare PHP, MySQL and Nginx versions to avoid incompatibilities with newer versions |
| Configuration files | Record virtual host configs, cron jobs (crontab -l) and SSL certificate locations |
| Hard-coded IPs | Check whether the old server's IP is hard-coded in your application or configs |
| Mail and third parties | Confirm whether MX records, API whitelists, payment callback URLs, etc. depend on the old IP |
| DNS TTL | Lower the TTL at least 24 hours in advance |
Log in to your domain's DNS management panel and change the TTL of the site's A records from the default (commonly 3600 seconds or more) to 300 seconds, or even 60 seconds. Wait at least one original TTL period before the actual cutover so that recursive DNS caches everywhere expire. You can check the current TTL with:
dig example.com A +noall +answer
The number after the domain name in the output is the remaining TTL in seconds.
On the target server, generate a key and push it to the source server (we use a "pull" approach so that you work from the new machine):
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
ssh-copy-id -p 22 root@SOURCE_SERVER_IP
Replace
SOURCE_SERVER_IPin the commands with the source server's IP address.
Run this on the target server (example syncing the website directory):
rsync -avzP -e "ssh -p 22" root@SOURCE_SERVER_IP:/var/www/ /var/www/
Options: -a archive mode, preserving permissions, ownership and timestamps; -v verbose output; -z compress during transfer; -P show progress and allow resuming partial transfers. Note that the trailing / on the source path means "sync the directory's contents"; leaving it out adds an extra level of nested directory.
Before the real run, add -n (--dry-run) to preview which files will be transferred. Use --exclude to skip cache or log directories:
rsync -avzPn --exclude 'cache/' --exclude '*.log' -e "ssh -p 22" root@SOURCE_SERVER_IP:/var/www/ /var/www/
The initial full sync can run while the website is live without affecting the business.
Export the database on the source server. For InnoDB tables, --single-transaction produces a consistent snapshot without locking tables:
mysqldump -u root -p --single-transaction --routines --triggers --events --default-character-set=utf8mb4 dbname | gzip > /root/dbname.sql.gz
Transfer it to the target server:
rsync -avP -e "ssh -p 22" root@SOURCE_SERVER_IP:/root/dbname.sql.gz /root/
On the target server, create the database and user, then import:
mysql -u root -p -e "CREATE DATABASE dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u root -p -e "CREATE USER 'dbuser'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD'; GRANT ALL PRIVILEGES ON dbname.* TO 'dbuser'@'localhost'; FLUSH PRIVILEGES;"
gunzip < /root/dbname.sql.gz | mysql -u root -p dbname
Replace
STRONG_PASSWORDwith a strong password of your own.
After importing, spot-check that the number of tables matches:
mysql -u root -p -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='dbname';"
Instead of changing DNS, temporarily point the domain to the new IP in your local computer's hosts file (on Windows it is at C:\Windows\System32\drivers\etc\hosts; on macOS/Linux it is /etc/hosts):
203.0.113.20 example.com www.example.com
Check key functions one by one, such as the homepage, login, uploads and payment callbacks. Once everything works, remove the hosts entry.
--delete (it deletes extra files on the target, so use it with care).We recommend keeping the source server for at least 3–7 days before releasing it, so you can roll back if needed.
Just run the same command again. rsync skips files that have already been transferred, and the -P option also allows resuming large files.
Add --quick to reduce memory usage, and pipe through compression to export and transfer at the same time. For databases of tens of GB or more, consider physical backup tools (such as Percona XtraBackup or mariabackup) or migrating via primary/replica replication.
This is usually caused by a character set mismatch between export and import. Make sure you specify --default-character-set=utf8mb4 when exporting, and that the target database also uses utf8mb4.
This happens because some ISPs' DNS caches have not expired yet, and it usually resolves itself within the original TTL period. It is also why you should keep the old server for a few days.
The keys to a smooth migration are: "lower the TTL early, do a full sync then an incremental one, and test before you cut over." If you plan to move your website or business to IMIDC, we offer a free migration assistance service: after you provision a cloud server or dedicated server in Hong Kong, Japan, Singapore, the US or another location, submit a ticket describing your source environment and migration needs, and our technicians will work out a specific plan and time window with you. If you have any questions during the migration, you can get support at any time through our 24/7 ticket system.