Similar to the feeling of moving to a different city, migrating a WordPress website to a new server or domain can be a bit worrisome. There are always small details that need attention, and missing one of them can lead to unnecessary headaches.
Migrating a WordPress site is not an overly complex process, but I’ve seen plenty of moves fail on the same handful of missed details. This guide starts with the manual method through your hosting panel, then covers the command-line route with SSH, WP-CLI, and Git, and ends with the most common problems and a cutover checklist.
Comfortable with the command line? Jump to the SSH and WP-CLI route
For the manual method, make sure you have the following:
- Access to the WordPress Dashboard (WP-ADMIN).
- Access to the hosting server’s management interface (e.g., cPanel).
- SFTP access to both servers (not strictly necessary; you can use the File Manager in the management interface).
If you prefer to use a plugin to save time, you can take a look at the post How to Copy, Duplicate, and Backup WordPress Site Using the Duplicator Plugin.
Which Migration Method Should You Use?
There is more than one way to move a WordPress site. The right one depends on the size of the site and how comfortable you are with a terminal.
| Method | Best for | Skill level |
|---|---|---|
| Migration plugin (e.g., Duplicator) | Small to medium sites and one-off moves | Beginner |
| Manual, through the hosting panel | Full control without touching the command line | Intermediate |
| SSH and WP-CLI | Large sites, repeat moves, servers without cPanel | Advanced |
| Git plus SSH | Sites whose code is already under version control | Advanced |
| Your new host’s migration service | Anyone moving to a host that offers one | None |
Before You Start: Prepare the Migration
A few minutes of preparation prevents most of the problems described later in this guide:
- Take a full backup of the files and database. See the guide on how to back up and restore a WordPress site.
- Compare PHP and MySQL/MariaDB versions. The new server should run the same versions or newer ones that your theme and plugins support.
- Lower the DNS TTL of your domain to a few minutes, a day or two before the move, so the final DNS switch takes effect quickly.
- Remove Wordfence Extended Protection if you use the Wordfence firewall in optimized mode. It points to an absolute file path on the old server and can cause a 500 error on the new one.
- Plan a quiet window for stores and membership sites. Orders, sign-ups, and comments made on the old server after you export the database will not exist on the new one.
Manual Migration of a WordPress Site to a New Server
In short, you transfer the files from the current server to the new one, create a database on the new server and import your site’s database into it, and point wp-config.php at that new database. If the domain changes too, you also update the URLs stored in the database.
Step 1: Download the Site Files to Your Computer
The first thing you need to do is download your site files to your computer. Connect to the server using FTP (preferably over SFTP) and download the folder containing WordPress. In most cases, the folder will be public_html or www.
Make sure your FTP client shows hidden files. Files that start with a dot, such as .htaccess and .user.ini, are often hidden by default and easy to leave behind.
Alternatively, you can use the hosting management interface (cPanel, Plesk, etc.). Go to the File Manager, compress the files into a Zip file before downloading, and save a lot of time.
You can even download the compressed file from the same interface without the need for FTP. Your choice.
Step 2: Download the Database from the Current Server
Once the download is complete, you need to download the database to your computer. To do this, access phpMyAdmin in the admin interface of the current server.
Click on your site’s database and then click on Export in the top toolbar. Choose the quick option under Export method and click Go to download the database.
If the database is very large, phpMyAdmin may time out on export or hit the upload size limit on import. In that case, the SSH and WP-CLI route described below is the more reliable option.
Step 3: Upload the Files to the New Hosting Server
At this point, you have everything you need from the old server. Now connect to the new server using SFTP and upload your site files. You can also use the File Manager in the management interface instead.
Either way, if you uploaded a Zip file, you need to extract it, and you can do this only through the File Manager in the server’s management interface.
Step 4: Create a Database on the New Hosting Server
Once the files are uploaded, you need to create a new database on the new server and import the database file you downloaded earlier.
To create a new database, go to MySQL Databases in the server’s management interface, click on Create New Database, and choose a name for the database.
Then, go to Add New User on the same screen. Choose a username and password, create a new user by clicking Create User.
Then, scroll down to the Add User to Database section, choose the username and the database you created, and click Add.
In the next screen, click on All Privileges to grant all the necessary permissions to the user and make the changes by clicking the Make Changes button.
Important note: In the upper part of this screen, you’ll see the database name and the username. Remember or note them down, as we will use them in the next step.
Step 5: Update wp-config.php for the New Database
You need to edit the existing wp-config.php file in the main WordPress directory so the site can connect to the new database. You need to change a few details in this file:
- DB_NAME – The name of the database.
- DB_USER – The username of the database.
- DB_PASSWORD – The password for the database.
- DB_HOST – The host of the database. (In most cases, it will be
localhost, but this depends on your hosting platform. If localhost doesn’t work, consult your hosting support).
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'xxxxxxxxx');
/** MySQL database username */
define('DB_USER', 'xxxxxxxxx');
/** MySQL database password */
define('DB_PASSWORD', 'xxxxxxxxx');
/** MySQL hostname */
define('DB_HOST', 'localhost');
Replace the xxxxxxx values with the information you noted in the previous step, according to your new database settings.
Leave the $table_prefix line as it is. It must match the prefix of the tables you are about to import, so only change it if the imported tables use a different prefix.
Step 6: Import the Database to the New Server
After creating a new database and updating wp-config.php, go to phpMyAdmin in the management interface of the new server and select the database you’ve just created. Click on it and then click on Import in the top toolbar.
Click on Choose File and select the database file you downloaded earlier and have on your computer. Click Go and wait for the operation to finish.
If you haven’t changed the domain, these are all the actions to perform. Of course, if you haven’t done this yet, you need to point the DNS servers of the domain to the new server.
This action is performed through the domain management with the company from which you purchased the domain (your domain registrar). The cutover checklist later in this guide covers what to check before and after the switch.
In any case, if you’ve performed the steps correctly, at this stage, you should succeed in connecting to the WordPress admin interface on the new hosting server.
At this point, go to the WordPress Dashboard > Settings > Permalinks and click Save Permalinks.
You might want to check the website on a temporary URL before switching the DNS. Alternatively you can test your website with your temporary address if you are using cPanel.
Step 7: Update Site URLs in the Database for the New Domain (Optional)
If you’ve changed the domain, you need to perform several additional actions, including updating the addresses in the database to the new domain:
A. Change the home and siteurl fields in the database
In phpMyAdmin, find the wp_options table and click on it to see the fields it contains.
It might have a different prefix other than
wp_but it will always end withoptions.
Find the siteurl and home fields and notice that their values are the old domain addresses. Edit the fields and replace the addresses with your new domain.
Alternatively, if you’re not comfortable working with phpMyAdmin, you can override these settings by editing the wp-config.php file and adding the following lines, replacing example.co.il with your new domain:
define( 'WP_HOME', 'https://example.co.il' );
define( 'WP_SITEURL', 'https://example.co.il' );
Use
https://if your site uses an SSL certificate. If you are migrating to HTTPS at the same time, see the complete HTTPS migration guide.
B. Perform a Search & Replace for all URLs in the database
The final action to take is to replace all the URLs in the database where the old domain is mentioned. To do this, go to the WordPress admin interface and install a search-and-replace plugin. Better Search Replace is a well-maintained, free plugin with over one million active installations.
After activating Better Search Replace, go to Tools > Better Search Replace. Enter your old domain in the Search field and your new domain in the Replace field. Select all database tables, and run a dry run first to preview the changes before applying them.
.sql file in a text editor. WordPress stores many settings as PHP serialized data, which records the length of every string. Changing a domain to one of a different length breaks those records, and widgets, theme options, and plugin settings silently reset. Better Search Replace and WP-CLI both handle serialized data correctly.The Developer Route: Migrating with SSH and WP-CLI
If you have SSH access to both servers, you can skip the downloads, the Zip files, and phpMyAdmin entirely. Files move directly from server to server, and WP-CLI handles the database, including the URL replacement.
This is my preferred method for large sites. It is faster, it doesn’t depend on PHP upload limits, and every step can be repeated if something goes wrong.
Step 1: Copy the Files Directly Between Servers
Log in to the new server over SSH and pull the files from the old server with rsync. Replace the user, host, and paths with your own:
rsync -avz --progress [email protected]:/home/user/public_html/ /home/newuser/public_html/
The trailing slash on the source path copies the contents of the folder rather than the folder itself. Hidden files like .htaccess are included automatically. If you run it again later to catch new uploads, add --exclude=wp-config.php so it doesn’t overwrite the credentials you set in the next step.
If rsync isn’t available, pack the site into a single archive on the old server and copy it with scp:
# On the old server
tar -czf site-files.tar.gz -C /home/user/public_html .
# On the new server
scp [email protected]:/home/user/site-files.tar.gz .
tar -xzf site-files.tar.gz -C /home/newuser/public_html
Step 2: Point wp-config.php at the New Database
Because you copied the files from the old server, wp-config.php still contains the old database credentials. Update them with wp config set instead of editing the file by hand:
wp config set DB_NAME new_database_name
wp config set DB_USER new_database_user
wp config set DB_PASSWORD 'new-password'
wp config set DB_HOST localhost
The database itself must already exist on the new server. On most hosting accounts you create it and its user in the control panel, exactly as in Step 4 of the manual method.
Step 3: Export and Import the Database
Export the database on the old server with wp db export, copy the file over, and import it on the new server. WP-CLI reads the credentials from wp-config.php, which is why the previous step comes first:
# On the old server, inside the WordPress directory
wp db export site.sql --add-drop-table
# On the new server, inside the WordPress directory
scp [email protected]:/home/user/public_html/site.sql .
wp db import site.sql
rm site.sql
Delete the SQL file once the import finishes, on both servers. Leaving a database dump inside the web root means anyone who guesses the filename can download it.
Step 4: Replace the Old Domain (If It Changed)
If the domain changed, wp search-replace updates every occurrence in the database, including serialized data. Start with a dry run to see how many rows will change:
wp search-replace 'https://old-domain.com' 'https://new-domain.com' --all-tables --precise --skip-columns=guid --dry-run
If the report looks right, run the same command without --dry-run, then flush the cache and the rewrite rules:
wp search-replace 'https://old-domain.com' 'https://new-domain.com' --all-tables --precise --skip-columns=guid
wp cache flush
wp rewrite flush --hard
The --skip-columns=guid flag leaves post GUIDs untouched, as the WP-CLI documentation recommends. If the old site still has http:// links in its content, run the command a second time for the http:// version of the old domain.
Where Git Fits In
Git is a great way to deploy code, but on its own it is not a migration tool. A typical WordPress repository tracks the theme, custom plugins, and mu-plugins. It does not include the uploads folder, the database, or wp-config.php, which holds secrets and should never be committed.
A typical .gitignore for a WordPress project looks something like this:
wp-config.php
.env
wp-content/uploads/
wp-content/cache/
wp-content/upgrade/
So if your site is already under version control, the migration splits into three parts:
- Code: clone the repository on the new server, or let your deployment pipeline push it there.
- Uploads: copy
wp-content/uploadswithrsync, as shown above. - Database: move it with
wp db exportandwp db import, then runwp search-replaceif the domain changed.
The real benefit of Git shows up after the move. Once the new server pulls code from a repository, whether through a CI pipeline that deploys over SSH or a hosting panel with Git integration, future changes ship with a push instead of an FTP upload.
Common Migration Problems and How to Fix Them
Most failed migrations end with one of the following symptoms. Each one has a known cause.
The Site Redirects to the Old Domain
The home and siteurl values in the options table still point to the old domain, or WP_HOME and WP_SITEURL are hardcoded in wp-config.php. Fix them, then clear any caching plugin and test in a private browser window, because browsers cache 301 redirects.
Error Establishing a Database Connection
The credentials in wp-config.php don’t match the new database, or DB_HOST isn’t localhost on your new host. See the full guide on fixing the Error Establishing a Database Connection.
A 500 Error or a Blank White Page
Something on the new server is still looking for a file path from the old one. The usual suspects:
- An
auto_prepend_fileline in.user.inior.htaccessthat loadswordfence-waf.phpfrom the old path. Update the path or remove the line, then re-optimize the Wordfence firewall. - The
advanced-cache.phporobject-cache.phpdrop-ins inwp-content, left over from a caching plugin or an object cache the new server doesn’t have. - A PHP version on the new server that your theme or plugins don’t support.
Enable WP_DEBUG_LOG in wp-config.php and check wp-content/debug.log to see the exact error.
“Unknown collation” During Import
The database was exported from MySQL 8, which uses the utf8mb4_0900_ai_ci collation, and imported into MariaDB or an older MySQL version that doesn’t recognize it. Replace the collation in the SQL file before importing:
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' site.sql
Unlike a domain change, this is safe to do in the file. Collation names appear in table definitions, not in serialized settings, so no string lengths change.
Inner Pages Return 404
The homepage loads but every other page shows a 404. The .htaccess file was not copied, usually because the FTP client hid it. Go to Settings > Permalinks and click Save Changes to regenerate the rewrite rules.
After the Move: Cutover and SEO Checklist
Once the site works on the new server, a few steps remain before and after you switch the DNS.
Before switching the DNS:
- Test the site on a temporary URL or through your hosts file.
- Set up an SSL certificate on the new server. Some hosts can only issue a free certificate once the domain points to them, so check this in advance.
- If orders or comments came in since you exported the database, export and import it again right before the switch.
- If you are moving the domain’s nameservers to a new provider, recreate the MX and TXT records there first, or email for the domain will stop working.
After switching the DNS:
- Purge every cache layer: the caching plugin, the server cache, and the CDN (e.g., Cloudflare).
- Make sure Settings > Reading > Discourage search engines from indexing this site is not checked. It is often turned on during staging and forgotten.
- Recreate any server cron jobs, and send a test email from a contact form to confirm that email delivery still works.
- Keep the old hosting account active for at least a week, until DNS propagation finishes and you are sure nothing is missing.
If You Changed the Domain
A domain change needs two extra steps to keep your search rankings. First, redirect every URL on the old domain to the same path on the new one with a 301 redirect. On an Apache server, add this to the .htaccess file of the old domain:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?old-domain.com$ [NC]
RewriteRule ^(.*)$ https://new-domain.com/$1 [R=301,L]
Second, verify both domains in Google Search Console and submit a Change of Address for the old site. Google’s site move guidelines are clear about how long the redirects should stay in place:
Keep the redirects for as long as possible, generally at least 1 year.
Expect some ranking fluctuations for a few weeks while Google recrawls the site and replaces the old URLs with the new ones.
FAQs
Common questions about migrating WordPress sites between servers and domains:
wp-config.php with the new database credentials.
wp-config.php, point your domain's DNS to the new server and save the Permalinks in the WordPress dashboard. No URL replacement is needed.
rsync, move the database with wp db export and wp db import, update the credentials with wp config set, and run wp search-replace if the domain changed. It is faster than the manual method and works well for large sites.
Summary
Manual WordPress migration involves downloading your files and database from the current server, uploading them to the new one, creating a fresh database, updating wp-config.php, and importing the data. If the domain changed, you also need to update the home and site URLs and run a search-and-replace across the database.
If you have SSH access, rsync and WP-CLI do the same job faster and handle large sites without upload limits. Git complements them by deploying the code, but the uploads and the database still move separately.
Whichever method you choose, test the site on the new server before switching DNS, and if the domain changed, set up 301 redirects and a Change of Address in Search Console. If you’d rather not handle the move yourself, I also offer a WordPress migration service.
