WordPress Migration to New Server: Complete Step-by-Step Guide

Priya

Content Writer & Researcher

Last Updated: 29 July 2026
WordPress Migration to New Server: Complete Step-by-Step Guide
🖥️

Migrate Your WordPress Site Without Losing a Single File

One missed file or corrupted serialized row can bring your entire WordPress site down — let CloudHouse's migration engineers handle it right the first time, with zero downtime and a verified rollback plan.

🖥️12,400+PCs Fixed
⭐4.9★Google Rating
⚡<15 minAvg. Response
🛡️ISO 27001Certified

Performing a wordpress migration to new server is one of the most critical — and error-prone — tasks a site owner or sysadmin will face. Whether you are upgrading your hosting plan, switching providers, or consolidating infrastructure, a single missed step can result in a broken site, missing media, or a corrupted database. This guide walks you through every step manually, using real commands, and highlights two things most other guides skip: the /etc/hosts trick to test before DNS cutover and the WP-CLI search-replace command that correctly handles serialized data.

Pre-Migration Checklist: What to Do Before Moving WordPress

Rushing into a migration is the fastest way to break a live site. Before touching a single file, complete these checks.

  • Confirm SSH access to both servers. You need root or sudo on both the old and new machine.
  • Record your current PHP version. Run php -v on the old server and match it on the new one to avoid fatal plugin errors.
  • Note your current MySQL/MariaDB version. A major version gap (e.g., MySQL 5.7 → 8.0) can cause InnoDB compatibility issues.
  • Check disk space. Run df -h on the new server — your new server needs at least twice the size of your WordPress directory free.
  • Lower your DNS TTL now. Log in to your domain registrar and set the TTL for your A record to 300 seconds (5 minutes). Do this 24 hours before the planned cutover so the change propagates before you switch IPs.
  • Disable caching plugins. Turn off WP Super Cache, W3 Total Cache, or LiteSpeed Cache before exporting. Cached files can mask real content and bloat your transfer size.
  • Document your wp-config.php credentials. Open /var/www/html/wp-config.php and note DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST.

If you would rather hand this checklist to a professional team, CloudHouse offers a fully managed server migration service that covers every step with zero-downtime guarantees.

💡 None of these worked? Skip the guesswork.

Get Expert Help →

Step 1: Backup Your WordPress Files and Database

1Create a full file archive on the old server

SSH into the old server and compress your entire WordPress root:

ssh user@old-server-ip
cd /var/www/html
tar -czf /tmp/wordpress_backup.tar.gz .
2Export the database with mysqldump

This produces a portable SQL dump of every table:

mysqldump -u DB_USER -pDB_PASSWORD DB_NAME > /tmp/wordpress_db.sql

Replace DB_USER, DB_PASSWORD, and DB_NAME with the values from your wp-config.php. If your database is large, add --single-transaction to avoid table locks on InnoDB:

mysqldump -u DB_USER -pDB_PASSWORD --single-transaction DB_NAME > /tmp/wordpress_db.sql
3Verify the backup files exist and have non-zero size
ls -lh /tmp/wordpress_backup.tar.gz /tmp/wordpress_db.sql
1Install the LAMP/LEMP stack

On Ubuntu/Debian:

apt update && apt install -y apache2 mysql-server php php-mysql php-curl php-gd php-mbstring php-xml php-zip

For Nginx instead of Apache, replace apache2 with nginx and configure a PHP-FPM pool.

2Create the database and user on the new server
mysql -u root -p
CREATE DATABASE new_wp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'new_wp_user'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON new_wp_db.* TO 'new_wp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
3Install WP-CLI on the new server

WP-CLI is essential for the serialized search-replace step later:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
wp --info
1Run rsync from the new server, pulling files from the old server
rsync -avz --progress user@old-server-ip:/var/www/html/ /var/www/html/

Flags explained:

  • -a — archive mode (preserves permissions, timestamps, symlinks)
  • -v — verbose output so you can see progress
  • -z — compress data in transit to reduce transfer time
  • --progress — shows per-file progress
2For very large sites, run rsync in two passes

A two-pass approach minimises downtime. Run the first pass while the old site is still live to transfer the bulk of data, then run a delta sync at cutover to catch only files that changed:

# Pass 1 — bulk transfer (run while old site is live)
rsync -avz --progress user@old-server-ip:/var/www/html/ /var/www/html/

# Pass 2 — delta sync at cutover (only changed/new files)
rsync -avz --progress --delete user@old-server-ip:/var/www/html/ /var/www/html/

The --delete flag in Pass 2 removes files on the destination that no longer exist on the source, keeping the two directories in perfect sync.

3Fix file permissions after transfer
chown -R www-data:www-data /var/www/html/
find /var/www/html/ -type d -exec chmod 755 {} \;
find /var/www/html/ -type f -exec chmod 644 {} \;
1Copy the SQL dump to the new server
scp user@old-server-ip:/tmp/wordpress_db.sql /tmp/wordpress_db.sql

Or use rsync for reliability on large dumps:

rsync -avz user@old-server-ip:/tmp/wordpress_db.sql /tmp/
2Import the database on the new server
mysql -u new_wp_user -p new_wp_db < /tmp/wordpress_db.sql

Alternatively, use WP-CLI if WP is already configured on the new server:

wp db import /tmp/wordpress_db.sql --path=/var/www/html
3Verify the import succeeded
mysql -u new_wp_user -p new_wp_db -e "SHOW TABLES;"

You should see all your WordPress tables: wp_posts, wp_options, wp_users, etc.

1Update wp-config.php with the new database credentials
nano /var/www/html/wp-config.php

Change these four lines:

define( 'DB_NAME',     'new_wp_db' );
define( 'DB_USER',     'new_wp_user' );
define( 'DB_PASSWORD', 'strong_password_here' );
define( 'DB_HOST',     'localhost' );
2Run WP-CLI search-replace to update all URLs

This is the most important step that most guides skip or do incorrectly. Never use raw SQL REPLACE() to update URLs in WordPress. WordPress stores widget settings, theme options, and plugin configurations as PHP serialized strings. A raw SQL replace changes the URL string length but does not update the byte-count prefix inside the serialized wrapper — this corrupts the data silently, breaking your widgets and theme settings.

WP-CLI's search-replace command understands serialized data and re-serializes correctly after every replacement:

# Dry run first — see what will change without modifying anything
wp search-replace 'https://old-domain.com' 'https://new-domain.com' --dry-run --path=/var/www/html

# Execute the real replacement
wp search-replace 'https://old-domain.com' 'https://new-domain.com' --path=/var/www/html

# If you are also changing www vs non-www, run it for both variants
wp search-replace 'http://old-domain.com' 'https://new-domain.com' --path=/var/www/html

Expected output shows a table of affected rows per table, for example:

+-----------------------+-------+--------------+------+
| Table                 | Column| Replacements | Type |
+-----------------------+-------+--------------+------+
| wp_options            | option_value | 47 | PHP  |
| wp_posts              | post_content | 312 | SQL |
| wp_postmeta           | meta_value | 8  | PHP  |
+-----------------------+-------+--------------+------+
3Flush the WordPress object cache and rewrite rules
wp cache flush --path=/var/www/html
wp rewrite flush --path=/var/www/html
1Find the new server's IP address
curl ifconfig.me   # run this on the new server

Suppose the new server IP is 203.0.113.50.

2Add a temporary override on your local machine (Mac/Linux)
sudo nano /etc/hosts

Add this line at the bottom:

203.0.113.50   yourdomain.com www.yourdomain.com

On Windows, the file lives at C:\Windows\System32\drivers\etc\hosts — edit it as Administrator.

3Open your browser and visit your domain

Your browser will now resolve your domain to the new server IP without any DNS change. The old site remains live for all other users. Test thoroughly:

  • Home page loads with correct content and images
  • Internal links navigate correctly (no redirect loops)
  • Admin login at /wp-admin works
  • Contact forms and checkout flows function
  • SSL certificate is valid (green padlock)
4Remove the /etc/hosts override when done testing

Delete the line you added and save. Your browser returns to resolving the domain via real DNS.

5Update DNS to point to the new server

Log in to your domain registrar and change the A record for yourdomain.com and www.yourdomain.com to the new server IP. Since you lowered the TTL to 300 seconds in the pre-migration checklist, propagation completes in about 5 minutes for most users.

Post-Migration Testing and Troubleshooting

Once DNS has propagated, run these checks from a device outside your network (or use a tool like whatsmydns.net) to confirm everything is healthy.

Essential Post-Migration Checks

  • HTTP response code. Run curl -I https://yourdomain.com — expect 200 OK. A 301 loop usually means WP_HOME/WP_SITEURL in wp-config.php is wrong.
  • Database connectivity. If you see "Error Establishing a Database Connection", double-check DB_HOST, DB_USER, DB_PASSWORD, and DB_NAME in wp-config.php.
  • Permalink structure. Visit Settings → Permalinks in WP Admin and click Save (even without changes). This regenerates the .htaccess rewrite rules on Apache.
  • 404 on posts but not home. Apache mod_rewrite is likely not enabled. Run a2enmod rewrite && systemctl restart apache2.
  • White screen of death. Enable WP_DEBUG by adding define('WP_DEBUG', true); to wp-config.php temporarily. Check /var/log/apache2/error.log or /var/log/nginx/error.log.
  • Missing images. Verify the wp-content/uploads directory was transferred. Check permissions: ls -la /var/www/html/wp-content/uploads/ — it should be owned by www-data.
  • SSL errors. If you moved to a new server, your Let's Encrypt certificate is tied to the old server. Run certbot --nginx -d yourdomain.com (or --apache) on the new server to issue a new certificate.
  • Plugin/theme conflicts. Disable all plugins via WP-CLI: wp plugin deactivate --all --path=/var/www/html, test the site, then re-enable plugins one by one.

Common Error Messages and Fixes

N. "Too Many Redirects" loop

This typically happens when siteurl and home in the wp_options table still point to the old URL despite the search-replace. Fix with:

wp option update siteurl 'https://new-domain.com' --path=/var/www/html
wp option update home 'https://new-domain.com' --path=/var/www/html

N. MySQL "Access Denied" on import

The user does not have the right privileges. Re-run the GRANT statement from Step 2 and verify with SHOW GRANTS FOR 'new_wp_user'@'localhost';

N. rsync "Permission denied (publickey)"

Copy your SSH public key to the old server: ssh-copy-id user@old-server-ip. If you do not have key-based auth, add --rsh="ssh -p 22" and use a password.

FAQs

See the FAQ section below for answers to the most common WordPress migration questions.

Migrating WordPress to a new server manually gives you complete control over every file and database row. The two steps that make or break a migration — testing with /etc/hosts before DNS cutover and using WP-CLI's serialization-aware search-replace instead of raw SQL — are what separate a clean migration from hours of troubleshooting. Follow this guide step by step and your site will be live on the new server with zero data loss and minimal downtime.

Need help from engineers who have done this hundreds of times? CloudHouse's server migration service handles WordPress migrations of any size with guaranteed uptime.

Get the Free Linux Server Admin Cheatsheet (PDF)

Essential commands for server management, networking, and troubleshooting — all on one printable page.

Running Linux servers? Let us manage them for you.

Our Managed Linux Server plans cover updates, security hardening, monitoring, and 24/7 incident response — so your servers stay up and your team stays focused.

  • Proactive OS patching and security updates
  • 24×7 monitoring with instant alerting
  • Backup configuration and disaster recovery
  • Dedicated Linux engineers on call
See Pricing Plans →

What our customers say

“Our production server went down at 2 AM. CloudHouse had it back online in under 20 minutes. Incredible response time.”

Arun S.

CTO, SaaS Startup

“They migrated our entire infrastructure from Ubuntu 18 to 22 with zero downtime. Couldn't have asked for better.”

Deepak N.

DevOps Lead

Frequently Asked Questions

A typical WordPress migration takes 1–3 hours for a site under 5 GB. Large sites with 20–50 GB of uploads can take 4–8 hours for the file transfer alone. Using the two-pass rsync approach (bulk transfer while the old site is live, then a fast delta sync at cutover) reduces actual downtime to under 5 minutes in most cases.

Need this done for you?

Server Migration Service

Move Linux and Windows servers with zero-downtime planning.

Learn more

Book your free 15-minute diagnosis

A certified technician will call you back within 15 minutes during business hours.

Share this article

Leave a Comment

Comments (0)

Loading comments...