Preparation
Before migrating: make a full backup (database + files), note the PHP/MySQL versions on the old server, and install matching ones on the new one.
Step 1: Export the Database
# On the old server
mysqldump -u wpuser -p wppassword wordpress_db > /tmp/wp_export.sql
# Transfer to the new server
scp /tmp/wp_export.sql root@NEW_SERVER_IP:/tmp/
Step 2: Transfer Files via rsync
rsync -avz --progress /var/www/wordpress/ root@NEW_SERVER_IP:/var/www/wordpress/
Step 3: Create the Database and Import
# On the new server
mysql -u root -p -e "CREATE DATABASE wordpress_db CHARACTER SET utf8mb4;"
mysql -u root -p -e "CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strong_password';"
mysql -u root -p -e "GRANT ALL ON wordpress_db.* TO 'wpuser'@'localhost';"
mysql -u root -p wordpress_db < /tmp/wp_export.sql
Step 4: Configure wp-config.php
define('DB_HOST', 'localhost');
define('DB_NAME', 'wordpress_db');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'strong_password');
Step 5: Configure Nginx
server {
listen 80;
server_name example.com www.example.com;
root /var/www/wordpress;
index index.php;
location / { try_files $uri $uri/ /index.php?$args; }
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Common Migration Errors
| Error | Cause | Fix |
|---|---|---|
| Error establishing a database connection | wp-config.php on the new server still has the old DB_HOST, DB_USER, or DB_PASSWORD | Check all four DB_* constants against the real credentials of the new database |
| mysqldump: Got error: 1045: Access denied for user | The database user was not created on the new server, or the password is wrong | Recreate the user with CREATE USER and re-issue GRANT |
| 413 Request Entity Too Large when importing via phpMyAdmin | The SQL dump size exceeds upload_max_filesize or client_max_body_size | Import from the console instead: mysql -u root -p wordpress_db < wp_export.sql |
| This site can't provide a secure connection after switching DNS | No SSL certificate has been issued yet for the domain on the new server | Issue a Let's Encrypt certificate (certbot) before switching DNS or right after |
| 404 Not Found on every page except the homepage | try_files isn't configured in Nginx on the new server, or the permalink rules weren't reloaded | Check the Nginx config and refresh permalinks: Settings → Permalinks → Save Changes |
Comparing Migration Methods
| Method | Control over the process | Size limit | Best for |
|---|---|---|---|
| mysqldump + rsync (this method) | Full | None | Large sites and non-standard server setups |
| Duplicator / All-in-One WP Migration | Medium | Up to 500 MB–2 GB on the free version | Small sites, migration without SSH access |
| Hosting panel migration tool | Low | Depends on the panel | Moving between plans of the same provider |
When This Method Is Not a Good Fit
- The old server has no SSH access (typical shared hosting) — use a panel export or a migration plugin instead
- The site is part of a WordPress Multisite network with shared tables across dozens of subdomains — migration needs a separate domain-mapping procedure
- The old IP runs a mail server or other services tied to that specific address — migrate those separately and in advance
- The business needs zero downtime — that calls for a blue-green setup with a load balancer, not a direct DNS switch
A detailed comparison of file-transfer tools is in "Transferring Website Files: rsync, SCP, and FTP", and mysqldump flags are covered in "mysqldump: MySQL Database Backup and Restore Guide".
Verifying the Result
After migrating, confirm the site works correctly on the new server:
# WordPress core file integrity
wp core verify-checksums
# The table count in the new database should match the old one
mysql -u wpuser -p -e "SHOW TABLES FROM wordpress_db;" | wc -l
# The homepage returns 200
curl -s -o /dev/null -w "%{http_code}\n" -H "Host: example.com" http://NEW_SERVER_IP/
# Check permalinks for 404s
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/2026/01/test-post/
If the site was set up from scratch, it's worth checking against "Install WordPress on a VPS Without Hosting: Full Setup" for the baseline PHP and Nginx environment requirements.
A manual migration gives full control over every step, but it demands care: don't rush the verification stage before switching DNS, or any mistakes will have to be fixed under live traffic instead.