How to Migrate a cPanel Account to a New Server
A cPanel migration goes wrong when DNS, mail and the database fall out of sync with each other. Here is the order that avoids downtime and lost email.
Migrating a cPanel account to a new server is mechanically simple, cPanel has built-in tools for exactly this, but it goes wrong in predictable ways: mail delivered to the old server after DNS has already switched, a database that finishes copying seconds after the site goes live and serves stale data, or a DNS TTL that was never lowered ahead of time turning a planned five minute cutover into hours of inconsistent results for different visitors.
Prepare before you touch anything
Most migration problems trace back to skipping this step. Lower the DNS TTL for the domain's A record and MX record well ahead of the actual cutover.
dig targetdomain.com +noall +answer
If it currently shows something like 86400 (24 hours), drop it to 300 (5 minutes) at least a day before you plan to migrate, then wait out the old TTL before proceeding. Changing the TTL itself does not take effect faster than the TTL that was in place before you changed it.
Copy the account with cPanel's own tools
WHM's Transfer Tool handles this end to end if both servers are under your control and reachable over SSH: log into WHM on the destination server, go to Transfers > Transfer Tool, and point it at the source server's root or reseller credentials.
For a single account without WHM access to both sides, the manual two-step process gives you the same result.
/scripts/pkgacct username /home/backups/
/scripts/restorepkg /home/backups/cpmove-username.tar.gz
This preserves file ownership and permissions, cron jobs, email accounts and their contents, DNS zone records, and SSL certificates where applicable, all in one operation, rather than you reconstructing each piece by hand and inevitably missing one.
Verify it works before touching DNS
Do not switch DNS yet. Confirm the site actually works on the new server first, using your local machine's hosts file to preview it against the new IP while the live domain still points at the old server.
echo "NEW_SERVER_IP targetdomain.com" | sudo tee -a /etc/hosts
Load the site in a browser and check it renders correctly, log into any application admin panel to confirm database connectivity, and send a test email through the account to confirm mail is actually functional on the new server before it becomes the only server handling it.
Handle the database and any last-minute changes
If the site takes writes (orders, form submissions, comments) between when you packaged the account and when you actually cut over DNS, that data exists only on the old server and needs a second, smaller sync immediately before cutover.
mysqldump -u root -p database_name > final_sync.sql
scp final_sync.sql newserver:/home/username/
Import it on the new server and confirm the row counts or latest timestamps match between old and new before proceeding, this closes the gap between when you first copied the account and the actual moment of cutover.
Cut over DNS and mail together
Update the domain's A record to the new server's IP and the MX record to point at the new server's mail service at the same time. Splitting these into separate steps is exactly what causes mail to keep arriving at the old server after the website has already moved.
Because you already lowered the TTL days earlier, this should propagate within minutes for most resolvers rather than the hours a default TTL would take.
Running this checklist correctly on one migration is manageable with good notes. Running it correctly, in order, on every account across a batch migration to a new server is where a missed step (an unlowered TTL, a database sync forgotten until after cutover) turns into hours of cleanup. BashPilot runs the packaging, restore, verification and cutover sequence as one request, and confirms each step before moving to the next rather than assuming the previous one worked.
Migrating an account with a live database in use
Packaging and restoring the account now. Once restored, I will verify the site loads correctly on the new server via a local check, then do a final database sync immediately before switching DNS to close the write gap.
- Package account on source server
- Restore on destination server
- Verify site and mail on new server before DNS changes
- Final database sync right before cutover
- Switch A and MX records together
Account restored and verified on the new server, mail sends correctly. Ready to run the final database sync and switch DNS. Confirm to proceed with the cutover.
mysqldump -u root -p shop_db > final_sync.sql && scp final_sync.sql newserver:/home/shop/
Try this on one of your own servers.
Start free trialVerify the migration actually completed
Do not consider it done the moment DNS propagates. Confirm the old server is genuinely out of the loop.
- Check the old server's mail logs 24 to 48 hours after cutover for any incoming mail still arriving there, some senders cache MX lookups longer than the TTL suggests.
- Confirm SSL certificates are valid on the new server, an expired or mismatched certificate after migration is one of the most common things overlooked in the rush of cutover.
- Watch the new server's error logs for the first day for anything that only shows up under real traffic, a staging test rarely exercises every code path a live site does.
Prevent problems on the next migration
- Keep DNS TTL permanently lower than the default 24 hours for domains you expect to migrate again in the future, it costs almost nothing in normal operation.
- Document the exact account list, cron jobs and any server-level customizations (custom PHP configs, cron scripts outside the account) before every migration, cPanel's transfer tool does not capture server-level changes outside the account itself.
- Keep the old server running, untouched, for at least a week after cutover, in case something surfaces that needs a reference to compare against.