Most "how to migrate WordPress" guides treat the move as an export-import job. Zip the files. Dump the database. Upload. Done. That approach works fine for a five-page brochure site. It falls apart the moment the site takes orders, logs in members, or runs a checkout. Somewhere between the export and the DNS switch, a customer places an order on the old server that the new one never sees.
Our team at BackupYourSite runs migrations as a restore-rehearsal instead. Treat the new host as a disaster-recovery target. Prove it works with the site still live on the old host. Only then cut traffic over. The downtime drops from hours to the length of a DNS TTL. The rollback plan is real because you tested it, not because you hope it works.
This runbook walks through that process end to end: pre-flight inventory, the out-of-band copy, verifying on the new box before DNS moves, handling writes made during the cutover window, search-and-replace rules, and the post-cutover checklist most teams skip. If you're searching for how to migrate a WordPress site to a new host, move a WordPress website to a new host, or transfer a WordPress site to another server without downtime, this is written for the moment you're actually about to do it.
Why a Migration Is Really a Restore
A WordPress site is three things: the files in wp-content, the MySQL or MariaDB database, and the server configuration around them. That configuration covers the PHP version, cron jobs, SSL, redirects, and mail. A migration moves all three to a new box. A disaster recovery event restores all three to a replacement box after the old one failed. The mechanics are identical.
The only difference is that, in a migration, the old server is still alive and serving traffic while you work. That's an advantage, not a complication. You get to verify the new server side by side with a known-good original before anyone's DNS resolver even knows the new IP exists.
Treating migration as "restore with a rehearsal" is what separates a clean cutover from a 2 a.m. incident. The opposite approach fails in a specific, repeatable way. The team uploads files through a browser-based plugin. The PHP execution limit times out on a 4GB uploads folder. The migration silently truncates. Nobody notices until a customer reports missing product images three days later.
Pre-Flight Inventory: What to Record Before You Touch Anything
Before copying a single file, document what the old server is actually running. This list takes 15–20 minutes. It prevents most of the failure modes that turn a planned move into an outage.
- PHP version — the exact minor version, for example PHP 8.2.14. A newer major version on the new host can break plugins that use deprecated functions.
- Database version and collation — MySQL 5.7 vs MariaDB 10.11 vs MySQL 8, and the table collation. Mismatches corrupt emoji and non-Latin text silently.
- Uploads folder size — run
du -sh wp-content/uploads. This single number tells you whether a plugin-based export will even complete before it times out. - Cron jobs — both WP-Cron scheduled events and any real system cron entries hitting
wp-cron.phpor running backup and cache scripts. - Mail configuration — the SMTP relay or transactional provider, such as SendGrid, Postmark, or SES, and its SPF and DKIM records, which live in DNS, not on the server.
- SSL certificate — the type, whether it's a Let's Encrypt auto-renew or a purchased cert, and its expiry date.
- Redirects — anything in
.htaccess, Nginx config, or a redirect plugin. These are the asset most often lost in a migration, and losing them quietly tanks rankings for pages that used to 301 somewhere useful.
The official WordPress.org documentation on moving an install confirms this footprint: files plus database plus server config, nothing hidden beyond that. A disciplined inventory makes the rest of the move mechanical instead of improvised.
Lower the DNS TTL 24–48 Hours Before the Move
This is the step almost every guide buries in a footnote. It's the one that determines whether your cutover takes 10 minutes or 2 days. DNS records carry a Time To Live value, or TTL — the number of seconds a resolver is allowed to cache an answer before checking again. Most domains ship with a TTL of 3,600 to 86,400 seconds, or 1 to 24 hours. If you change your A record and the old TTL was 24 hours, a meaningful share of visitors keep hitting the old server for up to a full day after you've already moved.
Two to three days before the planned cutover, drop the TTL on the relevant DNS records — A, AAAA, CNAME, and MX if mail is also moving — to 300 seconds, or 5 minutes. ICANN's technical FAQ on DNS resolution explains why timing matters here: resolvers across the internet cache independently, and the TTL governing propagation speed for next week's change has to already be short this week, not after you've made the change. Leave it at 300 seconds through the cutover and for roughly two weeks after, in case you need to roll back.
Copy Files and Database Out-of-Band, Not Through a Browser
Browser-based migration plugins are convenient for a 200MB blog. They're the wrong tool for anything bigger. They're bound by PHP's max_execution_time and upload_max_filesize, and a dropped connection mid-upload corrupts the archive with no clear error. Move the data over SSH instead.
- Files: run
rsync -avz --progress -e "ssh -p 22" /var/www/old-site/ user@new-server:/var/www/new-site/. Rsync resumes on interruption and only transfers what changed on a second pass, which matters for the delta sync below. - Database: run
mysqldump -u dbuser -p --single-transaction --routines --triggers old_db > backup.sql, thenmysql -u dbuser -p new_db < backup.sqlon the new server. The--single-transactionflag takes a consistent snapshot on InnoDB tables without locking the live site for writes.
The files transfer, not the database, is almost always the bottleneck. A database dump for even a large WooCommerce store is typically under 2GB. An uploads folder with five years of product photography routinely runs 20–60GB. Size your maintenance window around the files, and run the database dump last, immediately before cutover, so it captures the freshest state.
Verify on the New Server Before DNS Moves
This is the actual payoff of treating a migration as a restore rehearsal — and the step most guides skip entirely. Before changing any DNS record, edit your local machine's hosts file to point your domain at the new server's IP address, just for your machine. On Mac or Linux, that's /etc/hosts. On Windows, it's C:\Windows\System32\drivers\etc\hosts.
203.0.113.42 yourdomain.com www.yourdomain.com
Now browse the site as if it were live. Log in to wp-admin. Place a test order if it's a store. Check that uploaded images render, that search returns results, and that any custom login or membership plugin authenticates correctly. Confirm forms submit without a PHP error. This is a full checkout test on the new box, with zero visitors at risk, because nobody else's DNS resolver knows this IP exists yet.
We've found that this single step catches the majority of migration-breaking issues: a missing PHP extension, a wrong file permission on wp-content/uploads, an SSL certificate that didn't reissue. It catches them while there is still zero customer impact and zero time pressure to fix them.
Handling Writes Made During the Cutover Window
Even with a short TTL, there's an unavoidable window — typically 10 to 30 minutes — where some visitors still resolve to the old server while others already reach the new one. If the site only serves static content, this is harmless. If it takes orders, comments, or form submissions, you need a plan for writes that land on the old server after your database dump was already taken.
The cleanest fix is to freeze writes on the old server for the cutover window, rather than trying to merge two databases afterward. For WooCommerce or any store, this means briefly enabling a maintenance-mode plugin that blocks checkout — reads still work, carts just can't complete — for roughly 10 minutes while you take the final database dump, import it, and flip DNS. Trying to reconcile orders placed on two diverging databases after the fact is the single most error-prone part of any migration. A short, deliberate freeze costs far less than an hour of manual order reconciliation two days later.
Search-and-Replace: Only When the Domain Actually Changes
WordPress stores the site URL directly inside post content, serialized widget data, and the options table. It's not just in one settings field. If you're moving to a new host but keeping the exact same domain, there is nothing to search-and-replace. Every URL in the database is already correct, and running a search-replace tool anyway is how people corrupt serialized arrays by accident.
If the domain IS changing as part of the move, use WP-CLI's serialization-safe command rather than a plain text find-and-replace: wp search-replace 'https://olddomain.com' 'https://newdomain.com' --skip-columns=guid. The --skip-columns=guid flag matters. The GUID field is meant to be a permanent identifier, and changing it on existing posts breaks the way RSS readers and import tools deduplicate content.
The Post-Cutover Checklist
Once DNS has propagated and traffic is flowing to the new server, don't call the migration finished. Run this checklist on the live, cut-over site:
- SSL certificate — confirm it issued correctly for the new server's IP and isn't showing a mismatch warning. A Let's Encrypt reissue can take a few minutes after the first HTTPS request.
- Cron jobs — verify WP-Cron is firing. A plugin like WP Crontrol shows the next scheduled run. Confirm any system-level cron entries were recreated on the new server, not just copied as config files.
- Transactional mail and SPF — send a test order confirmation or password reset email and confirm it isn't landing in spam. If the new server has a different outbound IP, add that IP to your SPF record, or mail providers will start soft-failing authentication within days.
- Permalinks — resave permalink settings under Settings → Permalinks → Save. This forces the new server's web config to regenerate its rewrite rules. A copied-but-unregenerated rewrite rule is a common source of post-migration 404s.
- Object cache — if the site uses Redis or Memcached, confirm the new server's cache is actually connected. A silent fallback to no caching can look like "the site still works" while running 3 to 5 times slower.
- 404 sweep — crawl the site with a tool like Screaming Frog and compare the 404 list against a pre-migration crawl. Any URL that moved needs a redirect rule in the new server's config, since redirects are one of the assets most often lost in the files copy.
Keep a Rollback Plan That's Actually Real
Don't decommission the old server the moment DNS cuts over. Keep it running and paid for 14 days, with its DNS TTL still at 300 seconds. If something surfaces on day 3 that the pre-flight inventory and verification pass missed, you can point DNS back at the old server in minutes rather than restoring from a backup under pressure.
This is the same logic as any disaster recovery plan. A rollback path you haven't kept alive isn't a rollback path — it's a hope. On the backup side, this is exactly what BackupYourSite's automated WordPress backups are built for: a verified, restorable snapshot of the old environment sitting independently of both the old and new host, so the rollback doesn't depend on either server staying reachable.
If your current host's backup coverage is unclear, it's worth checking what's actually covered before you assume a "full backup" protects you during a migration window. Some hosts only snapshot the database. Others skip the uploads folder entirely once it crosses a size threshold. Our breakdown of what hosting companies do and don't back up covers this gap in detail, separate from the migration steps here.
What a Migration Like This Actually Costs
Budget for two things beyond your own time: a short overlap period where you're paying for both the old and new host, and the write-freeze window itself. The overlap typically runs the 14-day rollback period above, which at a mid-tier managed WordPress host runs $20 to $60 for the month depending on plan size — a small cost against the alternative of restoring from a cold backup under pressure with no live comparison server. The write-freeze window, 10 minutes for most stores, costs you whatever checkout volume you'd normally see in that slot. For a store doing modest traffic, that's rarely more than one or two carts, and scheduling the freeze for 3 a.m. in your lowest-traffic timezone shrinks it further.
Common Gotchas by Host Type
Not every host behaves the same way during a move. A few patterns come up again and again.
Shared hosting to shared hosting. File permissions often differ between providers. A folder that was 755 on the old host can arrive as 750 on the new one, which quietly blocks image uploads through wp-admin. Check permissions on wp-content/uploads right after the copy, not after a user reports a failed upload.
Shared hosting to a VPS. You gain root access, but you also lose the host's managed layer. Things like automatic PHP updates, a pre-configured object cache, and a managed firewall now need to be set up by hand. Budget an extra hour for this on a first VPS move.
Single server to a CDN-fronted setup. If the new host sits behind Cloudflare or another CDN, purge the CDN cache after cutover, not just the origin server's cache. A CDN edge node can keep serving the old server's cached HTML for its own TTL window, independent of DNS, which looks exactly like "the migration didn't work" when it actually did.
Multisite installs. Every sub-site's domain mapping and uploads path needs the same verification pass as the main site. A single successful test on the primary domain doesn't confirm the rest of the network moved cleanly.
Testing the Move Without Risking the Live Store
A staging copy on the new server is worth the extra 20 minutes it takes to set up. Clone the database into a second schema, point a subdomain like staging.newhost.yourdomain.com at it, and run your full pre-flight checklist there first. This catches configuration problems — a missing PHP extension, a disabled module, a firewall rule blocking outbound mail — before they ever touch the production cutover.
This staging pass typically surfaces one or two issues that the hosts-file verification alone would have missed, because a staging subdomain gets crawled by monitoring tools and browser extensions in a way a hosts-file override sometimes doesn't. It's a cheap insurance policy against a surprise during the real cutover window.
Frequently Asked Questions
How long does a WordPress migration actually take with zero downtime?
The file and database copy itself can run for hours in the background without any visitor impact, since the old server keeps serving traffic the whole time. The only customer-facing window is the write-freeze during final sync and DNS cutover, which typically runs 10 to 30 minutes for most WooCommerce sites, not hours.
Do I need to change anything if I'm keeping the same domain name?
No search-and-replace is needed if the domain doesn't change. Every URL already stored in the database is correct. You still need to update DNS to point at the new server's IP address, and you still need the pre-flight inventory, since PHP version, mail config, and cron are server-side, not domain-side.
What's the single most common migration mistake?
Changing DNS before verifying the new server actually works. A hosts-file override lets you test the fully live new environment, including checkout, login, and uploaded images, with zero visitors at risk before a single DNS resolver points anywhere near it.
How long should I keep the old host running after cutover?
14 days is a reasonable floor for most sites, longer for anything transactional. Keep its DNS TTL at 300 seconds the whole time, so a rollback, if you need one, takes minutes rather than a full day of propagation.
Can I migrate a WooCommerce store without losing any orders?
Yes, if you freeze checkout for the 10-minute write window instead of trying to merge two databases afterward. Take the final database dump right after the freeze starts, import it on the new server, flip DNS, then lift the freeze. Orders placed in that short window simply wait a few minutes rather than risk landing on a database that's about to be replaced.
A WordPress migration done this way is routine rather than risky: inventory first, out-of-band copy, verified on the new box before DNS moves, a short deliberate write-freeze instead of hours of downtime, and a rollback plan that's still alive for two weeks. See how BackupYourSite's automated backup and restore process works if you want the same rehearsed-restore discipline running on a schedule, not just on migration day. For questions specific to your setup, reach out to our team before you start the move, not after something's already missing.