Skip to content

Blog · How-to

Moving from shared hosting to a VPS without breaking your sites

Migrations go wrong in two ways, and only two: DNS was moved before the data was ready, or mail was forgotten entirely. Everything else is recoverable in minutes. Here is a sequence that avoids both, in the order that keeps a rollback available at every step.

Before you touch anything: drop your TTL

Do this at least 48 hours ahead. It is the single highest-value preparation step and the one most often skipped.

Your DNS records have a time-to-live, often 86400 seconds — a full day. Cut it to 300 while the old records are still live, wait for the old TTL to expire everywhere, and the world will pick up your eventual change in five minutes rather than a day. If the cutover goes wrong, that same five minutes is how fast you can undo it.

Raise it back to something sensible a week after the move.

1. Inventory what you actually have

Shared hosting accumulates things you have forgotten. Before migrating, list:

  • Every domain and subdomain, including the ones you no longer use
  • Every mailbox, forwarder and autoresponder — this is the one people miss
  • Cron jobs
  • The PHP version each site runs, which is often not the same
  • Any SSL certificates that are not Let's Encrypt
  • DNS records that point somewhere else entirely — Google verification TXT, SPF, DKIM, a subdomain aimed at a third-party service

That last group causes the most confusing failures, because those records live in the same zone you are about to replace and have nothing to do with the server you are moving.

2. Build the new server and put the sites on it

Do the whole build while the old host is still serving live traffic. Nothing is at stake yet, so take your time and get it right.

# Files
rsync -avz --progress olduser@oldhost:~/public_html/ /var/www/example.com/

# Database
ssh olduser@oldhost "mysqldump --single-transaction --quick -u USER -p DBNAME | gzip" \
  > example.sql.gz
gunzip < example.sql.gz | mysql -u newuser -p newdb

--single-transaction keeps the dump consistent on InnoDB without locking the live site. If the source is MyISAM you will need --lock-tables and a quiet moment.

3. Test before the world sees it

Point your own machine at the new server without changing public DNS, by editing your hosts file:

# /etc/hosts   (C:\Windows\System32\drivers\etc\hosts on Windows)
203.0.113.10  example.com www.example.com

Now browse the site as a real visitor would — the real domain, the real URLs, the real HTTPS certificate. Click through checkout. Submit a form. Log in to the admin. Then flush your DNS cache and remove the line.

This step catches hardcoded absolute URLs, missing PHP extensions and wrong file permissions while a mistake still costs you nothing.

4. Deal with mail before the cutover, not after

Here is the failure that ruins migrations. You move the A record, mail follows the MX record, and if the MX still points at the old host then mail keeps being delivered there — into mailboxes nobody is reading any more. It looks like mail has stopped, and the messages are not lost, just invisible. That can run for days before anyone notices.

Decide explicitly, in advance:

  • Mail is staying where it is. Easiest and usually correct. Do not touch the MX, and make sure the new server is not configured to deliver locally for that domain — otherwise it will helpfully swallow mail your own sites send to you.
  • Mail is moving too. Copy the mailboxes first with imapsync, run both in parallel over the cutover, and change the MX only once the copy is complete. Expect a long tail of client devices still authenticating against the old server for days.

We have watched an account keep sending invoices through a decommissioned server for thirty hours after a cutover because a desktop mail client had the old hostname saved. Check the old server's Sent folder afterwards. That is where the evidence is.

5. Freeze, final sync, cut over

  1. Put the old site into maintenance mode, or simply accept a short window where new orders may be missed.
  2. Re-run the rsync. It will only carry the changes and takes seconds.
  3. Re-dump and re-import the database. This is the step people forget — the first import is stale by now.
  4. Change the A record. With a 300-second TTL, the world follows within minutes.
  5. Watch the new server's access log fill up. Watch the error log harder.

6. Leave the old host running for a fortnight

Do not cancel immediately. It costs one more month and buys you a complete rollback, plus somewhere to find the file you did not know was there. Check the old server's logs after a week: anything still hitting it is something you missed.

The checklist for the day after

  • Does HTTPS work on both the apex and www?
  • Do outbound emails from the site arrive — and land in the inbox rather than spam? Your SPF record now needs to authorise a new IP.
  • Are the cron jobs running, and are they running as the right user?
  • Are backups configured on the new server? The old host's nightly backup was doing more for you than you realised.
  • Is anything still resolving to the old IP? dig +short example.com from a few networks.

Done in this order, the risky part of a migration is about five minutes long and reversible for every one of them.

Related reading

Need a server to try this on?

KVM, full root, billed in bitcoin. From $12.00 a month.

See the plans