How to migrate a WordPress site to a new host without downtime
Moving WordPress to a new host is a copy of two things, the files and the database, a test of that copy before any visitor is sent to it, and one DNS change. The old site keeps serving visitors until the new one is proven.
- By
- WP Ministry
- Published
In short
- Lower the TTL on the website's DNS record about a week ahead, and find out where your email is hosted before you touch DNS.
- Copy the files and the database, then point the copy's wp-config.php at the new database. Export to your home folder, never into the site's folder.
- Look at the copy on the new server through your own computer's hosts file before any DNS change.
- On a store, or a site with comments or forms, close the old site and copy the database again at the switch. What arrived in between is otherwise left behind.
- Maintenance mode switched on with WP-CLI ends by itself after ten minutes.
- Keep the old hosting until its log shows no visitors and your mail no longer depends on it.
A move between hosts is a copy of two things, the site's files and its database, then a test of that copy, then one DNS change. The old site keeps serving visitors the whole time. Nobody is sent to the new server until you have looked at the copy there and it works.
WordPress's documentation says that when the database and the address stay the same, you can move by copying your files and database. The care goes into what the copy does not carry, and into what the old site receives while you work.
This page is for a site that keeps its domain. The order of work for any move is in the website migration checklist. If the address changes too, read how to change your WordPress URL as well.
What moves with the copy, and what does not
| Part | Where it lives | How it reaches the new host |
|---|---|---|
WordPress, themes, plugins, uploads, wp-config.php, .htaccess | The site's folder | The file copy |
| Posts, pages, comments, users, settings, orders | The database | The database copy |
| Mailboxes | Wherever your mail records point | They do not move. See below. |
| The domain's DNS records | Wherever your DNS is managed | They stay, unless you change name servers |
| The SSL certificate | The old server | A new one is issued on the new server |
| Scheduled jobs and backups set up in the old control panel | The old host | Set them up again |
Before the move
Step 1: Lower the TTL on the website's DNS record
Every DNS record carries a TTL, a number of seconds. The DNS specification defines it as how long a resolver may cache the record before it must ask again. Until that time runs out, a visitor's internet provider keeps sending them to the old server.
Google's guidance for a change of hosting is to lower the TTL to a few hours, at least a week before the move. Do it early: a resolver that already holds the record keeps it for the old TTL. Change it where your DNS is managed, on the A record for the domain and on the record for
www. An AAAA record is the same thing for an IPv6 address. If the domain has one, lower it too.This prints the record as your resolver holds it now. The second column is the seconds left before it asks again.
bashdig example.com A +noall +answerStep 2: Find out where your email is hosted
Mail for your domain is routed by MX records, not by the website's record. List them. On Windows, use
nslookup -type=MX example.com.- The lines name a mail service. Your mailboxes are not at the old host. They keep working as long as the MX records survive the DNS change, along with the TXT records that say which servers may send mail for the domain.
- The lines name the old host's server, or a name under your own domain. Your mailboxes are at the old host and do not move with the site. Move them, or keep a mail plan there, before you cancel anything.
- The line names the domain itself, or nothing is printed. The mail standard says a sender looks up the address of the name in the MX record, and with no MX record it treats the domain's own address as the mail server. Either way, mail follows the website's record: change that record and mail goes to the new server. Sort this out with whoever runs your mail before the switch.
bashdig +short example.com MXStep 3: Note what the old server runs
In the old site's dashboard, go to Tools, then Site Health, then the Info tab. The Server and Database sections give the PHP version, the web server and the database version. Press "Copy site info to clipboard" and save the result.
Set the new account to the same PHP version, or a newer one your plugins support. WordPress recommends PHP 8.3 or greater, and MariaDB 10.11 or MySQL 8.0 or greater. Over SSH,
php -mlists the PHP extensions on a server, so you can compare the two lists. WordPress's hosting handbook names the extensions it needs. The PHP on the command line can differ from the one that serves the site, so take the version from Site Health.Note whether the database is MySQL or MariaDB. MariaDB's documentation warns that its export begins with a command that MySQL's client, and older MariaDB clients, can reject with an error. If an import on the new host stops on its first line, that is the cause. Ask the new host how it wants the file.
Step 4: Keep a full backup
WordPress's documentation says to begin a move by backing up the files and the database. The export and the archive made below are that backup, so download both to your own computer as well. The copy changes nothing on the old site, which stays your way back until you cancel it.
Copy the site by hand
This needs SSH access on both hosts and WP-CLI. Run the wp and tar commands in the site's main folder, the one that holds wp-config.php. The names and the address 203.0.113.10 are examples: use the new server's own IP address or the host name the new host gave you, not your domain, which still leads to the old server.
Step 1: Create an empty database on the new host
In the new host's control panel, create a database and a database user with a password, and give the user full rights on that database. Write down the name, the user, the password and the database host the panel shows.
wp db importdoes not create a database.If the new host installed a starter WordPress or left a placeholder page in the site's folder, empty the folder first.
Step 2: Export the database on the old host
This writes the whole database to one file. The
~/puts it in your account's home folder and not in the site's folder, where anyone who guessed its name could download it.bashwp db export ~/example-db.sqlStep 3: Archive the files
This packs everything in the folder into one compressed file, hidden files such as
.htaccessincluded. It needs free space of up to the size of the site.du -sh .prints that size.bashtar -czf ~/example-files.tar.gz .Step 4: Send both files to the new host
Run this on the old server. If the old host blocks outgoing SSH, download the two files to your computer over SFTP and upload them to the new account's home folder.
bashscp ~/example-db.sql ~/example-files.tar.gz newuser@203.0.113.10:~/Step 5: Check that both arrived whole
Run this on both servers. Each file must give the same long string on each. A file cut short in transfer gives a different one.
bashsha256sum ~/example-db.sql ~/example-files.tar.gzStep 6: Unpack the files on the new host
Run this in the new site's folder. It overwrites any file there that has the same name as one in the archive. Run it a second time later and it puts the old
wp-config.phpback.bashtar -xzf ~/example-files.tar.gzStep 7: Point the copy at the new database
The copy arrives with the old host's database details. These commands change the copy's
wp-config.phpand nothing else. Use the values from the first step. The last line prints the database name, so you can see it is the new one.bashwp config set DB_NAME new_database wp config set DB_USER new_user wp config set DB_PASSWORD 'new-password' wp config set DB_HOST localhost wp config get DB_NAMEStep 8: Import the database
Do this straight away. With an empty database, the copy offers WordPress's installer to anyone who reaches it.
bashwp db import ~/example-db.sqlStep 9: Confirm the copy reads its own database
This should print your site's real address. If it does, the files,
wp-config.phpand the database agree.bashwp option get home
Both files in the home folders hold everything in the site, password hashes and customer details included. Delete them from both servers once the move has settled.
The plugin route
A migration plugin makes the same two copies for you: it packs the files and the database on the old site and unpacks them on the new one. WordPress's documentation lists Duplicator among its links for moving a site. Duplicator's listing on WordPress.org says it packages the files and the database into a single file, which can be installed at the new location without installing WordPress first. Ask the new host whether it has a migration tool of its own, too.
A plugin does the copy. It does not lower the TTL, find your mailboxes, test the result or carry across what arrived after it ran. The rest of this page applies either way.
Test the copy before the switch
Your domain still leads to the old server. To see the copy at its real address, tell your own computer, and nobody else's, where the domain is.
Step 1: Put a marker on the new server
The two sites are identical, so give the new one a file the old one lacks. Run this in the new site's folder. Delete the file when the move is done.
bashecho "new server" > which-server.txtStep 2: Add a line to your computer's hosts file
The hosts file maps names to IP addresses, one line per address, and an entry in it overrides what DNS says. Add this line at the end, with the new server's address and your domain.
System File How to open it macOS /private/etc/hostsIn Terminal, sudo nano /private/etc/hosts. Save with Control-O, then Enter. Exit with Control-X.Linux /etc/hostsIn a terminal, sudo nano /etc/hosts.Windows C:\Windows\System32\drivers\etc\hostsOpen Notepad as an administrator, then open the file from Notepad. text203.0.113.10 example.com www.example.comStep 3: Confirm you are looking at the new server
Open
https://example.com/which-server.txt. The words "new server" mean you are on the copy. A 404 means you are still on the old server: close the browser completely and open it again. On Windows, runipconfig /flushdnsfirst.Step 4: Take the line out when you finish
Until you do, your computer ignores DNS for this domain.
curl can ask the new server directly, without the hosts file. Add -k while the new server has no certificate for your domain, so that curl skips the check.
curl -s --resolve example.com:443:203.0.113.10 https://example.com/which-server.txtThe certificate. Until the new server has a certificate for your domain, the browser warns before it shows the copy. That is expected at this stage, and you can choose to continue. If the browser does not offer that, get the certificate first by the DNS method described under the switch.
A temporary address. If the new host gives the account a temporary address of its own, WordPress sends a visitor from there straight to your real domain, because the database holds the real address. WordPress's documentation says to change the address temporarily if you test this way. Two lines in the copy's wp-config.php do it without touching the database. Remove them before the switch.
define( 'WP_HOME', 'https://temporary.example.net' );
define( 'WP_SITEURL', 'https://temporary.example.net' );What to check on the copy
- Pages and permalinks. The home page, a post, a page, a category and a search. A 404 on everything but the home page is in the table below.
- Login. Log in, open the dashboard, and read Tools, then Site Health, for anything the new server lacks.
- Media. Images in old posts, and one new upload.
- Forms. Send each one and see that the mail arrives.
- Checkout. Place an order with the payment method in test mode.
- HTTPS. Once the certificate is in place, the padlock on several pages.
- The firewall. Google's guidance is to check that the new host's firewall does not block Googlebot.
Content that changes during the move
The first copy is a photograph of one moment. Everything the old site receives after it stays on the old site.
| Kind of site | What arrives after the copy | What to do |
|---|---|---|
| A blog or brochure site, comments and forms off | Only what you publish | Freeze: publish and edit nothing until the switch is done |
| A site with comments, form entries or new accounts | Comments, entries, users | Copy the database again at the switch |
| A store | Orders, customers, stock levels | Copy the database again at the switch, with the store closed |
WooCommerce keeps orders in database tables, so a second database copy carries them. The second import replaces the copy's whole database. Anything you changed in the copy's dashboard while testing, test orders included, is overwritten, so make lasting fixes on the old site before this point. Changes to files, wp-config.php among them, stay.
Step 1: Close the old site
Run this on the old server. Visitors get "Briefly unavailable for scheduled maintenance. Check back in a minute." and nothing new can be written. WordPress treats maintenance mode as over once its file is ten minutes old, so the site reopens by itself. If the copy takes longer, run the command again with
--forceto start the ten minutes afresh.bashwp maintenance-mode activateStep 2: Export the database again
Maintenance mode is a file in the site's folder, not a setting in the database, so it does not travel with the export.
bashwp db export ~/example-db-final.sqlStep 3: Send it across with the new uploads
rsyncsends only the files that are new or changed. The slash at the end of the first path means "the contents of this folder". Put your own folder name in the second path, then send the export withscpas before.bashrsync -az wp-content/uploads/ newuser@203.0.113.10:public_html/wp-content/uploads/Step 4: Import on the new server
Check the server first. This replaces every table in the copy's database with the old site's as it stood a moment ago.
bashwp db import ~/example-db-final.sqlStep 5: Keep the old site closed, then change the DNS
For a while after the switch, some visitors still reach the old server. An order placed there would be left behind. Before the ten minutes run out, run the line below in the old site's folder, and then make the switch as the next section describes.
The line writes a maintenance file that does not expire, so those visitors see the notice until their provider lets the old record go. The lower the TTL, the shorter that lasts. WP-CLI does not recognize this file: to reopen the old site, delete it with
rm .maintenance.bashecho '<?php $upgrading = time();' > .maintenance
Make the switch
Change the A record, or the name servers. Changing the A record, and the AAAA record if there is one, where your DNS is managed now is the smaller change. Every other record stays as it is, mail included. Changing name servers hands the whole domain's DNS to another company. Every record must exist there first: the MX records, the TXT records your mail relies on, and every subdomain. Copy them across and compare the two lists before you change anything.
Get the certificate onto the new server. Let's Encrypt, a free certificate authority, documents how it checks that you control a domain. Its HTTP-01 method fetches a file from your domain over the web, which works only once the domain leads to the new server. Its DNS-01 method reads a TXT record in your DNS, which works before the switch. Ask the new host which it uses. If the certificate can only be issued afterward, issue it the moment the DNS changes. Until then, visitors who reach the new server over https see the "Your connection is not private" warning. The steps are in how to install a free SSL certificate on WordPress.
Tell which server you are seeing. Take the line out of your hosts file first. Then open https://example.com/which-server.txt again: the words mean your computer now reaches the new server. dig +short example.com A prints the address your resolver gives out. Other visitors switch as their own resolvers let the old record go.
After the switch
- Email. Send a message to an address at your domain and reply to it. Send each form on the site. The site's own mail now leaves from the new server, and WordPress not sending email covers what to do if it does not arrive.
- Scheduled jobs. A cron job set up in the old control panel did not come with the files. Create it again on the new host.
- Backups. The old host's backups stay with the old host. Set up a schedule on the new one and prove that it runs.
- Redirects. Rules in
.htaccesscame with the files. WordPress's documentation says nginx has no such file, so on an nginx server those rules do nothing until the host adds them to its own configuration. Run a few old addresses through the redirect checker. - Search engines. If Search Console was verified with an HTML file, see that the file is on the new server: Google says removing it loses verification. Google also says a drop in its crawl rate straight after the move is normal and is followed by a steady rise over a few days. The site health check shows whether a page answers, how it is secured and what it tells search engines.
- The TTL. Put it back to its earlier value once the site has settled.
- The old hosting. Google's guidance is to watch the logs of both servers and to shut the old one down once its log shows no traffic. Before you cancel, also be sure that your mail does not depend on it and that you hold a final backup.
What goes wrong, and the page that fixes it
| What you see on the new server | The likely cause after a move | Where the fix is |
|---|---|---|
| "Error establishing a database connection" | A database name, user, password or host in wp-config.php that does not match the new database | Error establishing a database connection |
| The home page loads and every other page is a 404 | .htaccess was not copied, or the new server does not pass addresses to WordPress | 404 errors on posts and pages that exist |
| A missing padlock, or images and styles that do not load over https | Addresses that still begin with http | Mixed content warnings |
| Uploads and updates fail, or WordPress asks for FTP details | Files owned by the wrong account after unpacking, or the wrong modes | WordPress file permissions |
| A critical error or a blank page on some screens | A PHP version or an extension that differs from the old server | WordPress hosting problems |
When to hand it over
Get help when the site is a store that cannot close, when you have no SSH access on one side, or when you cannot tell where your mail lives.
Our WordPress migration service moves one WordPress site from one host to another and tests the copy on the new host before the DNS is changed.
Common questions
Will my site go down during the move?
It does not have to. The old site serves visitors until the DNS changes, and the new one is already working by then. The exception is a store or a site that takes comments or forms: it is closed while the second database copy is made, and visitors whose provider still holds the old record see the maintenance notice until it lets go.
How long does the DNS change take to reach everyone?
A resolver may keep its copy of the record for as long as the TTL says before it asks again, so visitors move across one resolver at a time. That is why the TTL is lowered a week ahead, and why the old server stays up until its log is quiet.
Do I need to change the WordPress address?
No. The domain stays the same, so the two addresses under Settings, then General, stay as they are. They change only if you test at a temporary address, and then only in the copy's wp-config.php.
Will I lose email when I move the site?
Not if the mail records are left alone and the mailboxes are not at the old host. Check the MX records first. If the mailboxes are at the old host, they stay there until you move them, and they go when that plan is canceled.
Can I move the site without SSH?
Yes. Use a migration plugin, or download the files over SFTP and export the database with phpMyAdmin, which WordPress's backup documentation describes. The steps around the copy are the same.
- ResourceWebsite migration checklist: before, during and after the move
- ResourceWebsite redesign SEO checklist: what to record, map and check on a rebuilt site
- Cost guideWordPress migration cost: which job you are being quoted for, and what moves the price
- GuideTraffic dropped after a website redesign: what to check on a WordPress site, in order
- GuideHow to migrate a website without losing SEO: what Google and Bing document
- GuideHow to migrate from Shopify to WooCommerce

