Switching VPS providers is one of the most stressful operations a server administrator faces — done wrong, it means hours of downtime, lost emails, and broken SSL certificates. Done right with a structured process, migrating from one VPS provider to another can happen with zero downtime and zero data loss. This guide walks through every step: pre-migration audit, data transfer with rsync, DNS cutover timing, and post-migration verification.
Why Migrate VPS Providers — and What Can Go Wrong
Common reasons hosting teams migrate to a new VPS provider include better pricing, improved hardware (NVMe vs spinning disk), geographic relocation for latency, superior support SLAs, or a provider going out of business.
Common migration mistakes that cause downtime:
- Cutting DNS over before the new server is fully verified
- Forgetting to transfer SSL certificates, causing browser warnings immediately after cutover
- Not accounting for email queues — messages in transit during the cutover window get lost
- Failing to replicate cron jobs, custom systemd services, or firewall rules
- Ignoring database replication lag on MySQL/MariaDB slaves
A structured migration plan eliminates all of these. The key principle: the new server must be 100% verified and live-tested before DNS is changed.
Pre-Migration Checklist: Audit Before You Move
Before touching the new server, document everything on the source server. Run this audit and save the output:
# Running services
systemctl list-units --type=service --state=running
# Installed packages (Debian/Ubuntu)
dpkg --get-selections > /root/packages.list
# Installed packages (CentOS/AlmaLinux/Rocky)
rpm -qa > /root/packages.list
# Cron jobs (all users)
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null && echo "--- $user ---"; done
# Open ports / firewall rules
ss -tlnp
iptables -L -n -v
ufw status verbose 2>/dev/null
# Disk usage
df -h
du -sh /var/www/* /home/* 2>/dev/null | sort -rh | head -20
# Active databases
mysql -e "SHOW DATABASES;" 2>/dev/null
# Environment variables and app configs
ls /etc/*.conf /etc/nginx/sites-enabled/ /etc/apache2/sites-enabled/ 2>/dev/null
Save all output to a migration notes file. This becomes your verification checklist on the new server.
💡 None of these worked? Skip the guesswork.
Get Expert Help →Step-by-Step VPS Migration Process
Create the new VPS at your target provider. Choose the same OS version as the source to simplify package compatibility. Before transferring any data, run the initial hardening steps: update all packages (apt update && apt upgrade -y or dnf update -y), configure SSH key-only authentication, disable root password login in /etc/ssh/sshd_config, and install your preferred firewall (UFW, CSF, or firewalld). Install the same web server, PHP version, and database version as the source server.
On the source server, generate a migration key pair and copy the public key to the destination:
ssh-keygen -t ed25519 -f /root/.ssh/migration_key -N ""
ssh-copy-id -i /root/.ssh/migration_key.pub root@NEW_SERVER_IP
Test the connection: ssh -i /root/.ssh/migration_key root@NEW_SERVER_IP "hostname". This key is used for all rsync transfers — delete it from both servers after migration is complete.
rsync is the preferred tool for VPS migration because it is resumable, compresses data in transit, and can run incrementally — you run it once for the bulk transfer, then run it again just before cutover to sync only the files that changed.
# Initial bulk sync (run this hours or days before cutover)
rsync -avz --progress -e "ssh -i /root/.ssh/migration_key" /var/www/ root@NEW_SERVER_IP:/var/www/
# Sync home directories
rsync -avz --progress -e "ssh -i /root/.ssh/migration_key" /home/ root@NEW_SERVER_IP:/home/
# Final incremental sync (run this 5 minutes before DNS cutover)
rsync -avz --delete -e "ssh -i /root/.ssh/migration_key" /var/www/ root@NEW_SERVER_IP:/var/www/
The --delete flag on the final sync ensures files deleted on the source are also removed on the destination, keeping both servers in perfect sync.
# On source: dump all databases
mysqldump --all-databases --single-transaction --routines --triggers -u root -p > /root/all_databases.sql
# Transfer to destination
rsync -avz -e "ssh -i /root/.ssh/migration_key" /root/all_databases.sql root@NEW_SERVER_IP:/root/
# On destination: import
mysql -u root -p < /root/all_databases.sql
For large databases (10GB+), use mydumper and myloader for parallel dump/restore, which is significantly faster than mysqldump.
# Copy Let's Encrypt certificates
rsync -avz -e "ssh -i /root/.ssh/migration_key" /etc/letsencrypt/ root@NEW_SERVER_IP:/etc/letsencrypt/
# Copy custom/commercial certificates
rsync -avz -e "ssh -i /root/.ssh/migration_key" /etc/ssl/custom/ root@NEW_SERVER_IP:/etc/ssl/custom/
After the transfer, on the new server verify the certificates are recognised: certbot certificates. Update your web server virtual host configs to point to the correct certificate paths.
# Nginx virtual hosts
rsync -avz -e "ssh -i /root/.ssh/migration_key" /etc/nginx/sites-available/ root@NEW_SERVER_IP:/etc/nginx/sites-available/
rsync -avz -e "ssh -i /root/.ssh/migration_key" /etc/nginx/sites-enabled/ root@NEW_SERVER_IP:/etc/nginx/sites-enabled/
# Apache virtual hosts
rsync -avz -e "ssh -i /root/.ssh/migration_key" /etc/apache2/sites-available/ root@NEW_SERVER_IP:/etc/apache2/sites-available/
# PHP configuration
rsync -avz -e "ssh -i /root/.ssh/migration_key" /etc/php/ root@NEW_SERVER_IP:/etc/php/
# Cron jobs
crontab -l | ssh -i /root/.ssh/migration_key root@NEW_SERVER_IP "crontab -"
Before changing any DNS, test every site on the new server by temporarily overriding DNS on your local machine. On your workstation, edit /etc/hosts (Linux/Mac) or C:\Windows\System32\drivers\etc\hosts (Windows):
NEW_SERVER_IP yourdomain.com www.yourdomain.com
Browse every page of your site, test logins, check that SSL shows valid in the browser, submit test forms, and run your application's test suite if one exists. Only remove this hosts file entry and proceed with DNS cutover once everything is verified working.
At least 24–48 hours before the planned cutover, lower your DNS TTL to 300 seconds (5 minutes). This ensures that when you change the A record, propagation completes in under 10 minutes rather than up to 24 hours. After migration is stable (48 hours), raise TTL back to 3600 or higher.
The cutover window procedure:
- Run the final rsync incremental sync to capture any files changed since the initial bulk transfer
- Put the source server into maintenance mode (or enable a short maintenance page)
- Take a final database dump and import it on the destination
- Update the DNS A record to point to the new server's IP
- Monitor DNS propagation:
watch -n 10 "dig +short yourdomain.com @8.8.8.8" - Once propagation is confirmed, remove the maintenance page on the new server
Email is the most common casualty of VPS migrations. To prevent lost messages:
- Lower MX record TTL 48 hours before cutover along with the A record
- Transfer all mailbox data:
rsync -avz /var/mail/ root@NEW_SERVER_IP:/var/mail/andrsync -avz /home/*/Maildir/ root@NEW_SERVER_IP:/home/(path depends on your mail server) - Start Postfix/Dovecot on the new server before updating MX records so incoming mail is accepted immediately
- Keep the old server's mail server running for 24 hours after MX change to catch any messages routed to the old IP during propagation
Post-Migration Verification Checklist
- Web: All sites load on HTTPS without certificate warnings
- Database: Application connects and data is intact — run
SHOW TABLES;and check row counts on key tables - Email: Send and receive test emails; check spam folder delivery
- Cron jobs: Verify cron is running:
crontab -land check/var/log/syslogfor cron execution entries - SSL: Run
curl -vI https://yourdomain.com 2>&1 | grep SSLto confirm certificate is valid and from the new server - Firewall:
ufw statusorcsf -l— confirm rules are active - Performance: Run a quick load test with
ab -n 100 -c 10 https://yourdomain.com/ - Monitoring: Update any uptime monitoring, Zabbix, or Grafana agents to the new server IP
Keep the old VPS running for at least 72 hours after migration is confirmed stable. Once you're satisfied, decommission it — but take a final snapshot first in case an edge case surfaces later.
When to Hire a Managed Migration Service
DIY VPS migration works well for single-site setups with simple stacks. For environments running 50+ websites, custom database clusters, real-time applications, or strict uptime SLAs, the risk of missed configuration details is significant. A managed migration service handles the full process — pre-migration audit, parallel environment setup, live testing, cutover coordination, and post-migration monitoring — with guaranteed zero downtime. CloudHouse Technologies provides expert server migration services for businesses that cannot afford migration-related downtime.
