Operations

Moving a WordPress site from shared hosting to a VPS

You have outgrown shared hosting. The 503 errors on every traffic spike, the "too many connections" MySQL errors, the support ticket for every configuration change, you need real resources. A migrate wordpress to vps project sounds daunting, but with the right sequence it runs with zero downtime and zero lost requests. This guide walks you through the exact steps: backup your site on the old host, provision your new VPS, replicate everything, flip the DNS record, and run the final sync. You keep your site live until the very last second.

  • Key takeaways: You migrate WordPress to VPS using rsync for the files and mysqldump + mysql for the database, with a controlled DNS cutover. Total downtime: zero if you follow the order. A full site (5 GB files, 2 GB database) takes roughly 30 minutes total, most of which is the initial rsync.

迁移WordPress的关键在DNS TTL与切换顺序,而不是复制文件。

A WordPress migration turns on DNS TTL and cutover order, not on copying files.

Prerequisites

  • A new VPS running Ubuntu 24.04 LTS with root or sudo access, for example, a WordPress VPS from thueVPS with NVMe storage and a dedicated IPv4 in Vietnam.
  • The VPS should have at least 2 GB RAM (VNLite tier or higher) for a typical WordPress site.
  • SSH access to both the old shared hosting server and the new VPS.
  • A domain name whose DNS you control.
  • Basic familiarity with the command line.

Why migrate WordPress to a VPS, the real break point

Shared hosting packages are fine for a personal blog that gets a few hundred visitors a day. They break when you install WooCommerce, run a membership site, or push the smallest custom module that needs exec() or fsockopen(). The CPU allowance is shared between dozens of tenants; MySQL connection limits as low as 25 are common. When you migrate WordPress to VPS you get dedicated vCPUs, RAM you can actually allocate, and the freedom to tune nginx, PHP-FPM, and MariaDB for your exact workload.

Beyond performance, you also control the IP, important if your users are in Vietnam and you want a local IPv4 for lower latency and better deliverability to Vietnamese email providers. A Vietnam VPS routes domestically within Viettel IDC, VNPT IDC, or CMC Telecom (the three major data center operators in Vietnam, all Tier 3), avoids international hops for domestic visitors, and gives you a clean IP for outbound SMTP. We will cover why that matters in the DNS section.

Step 1, Set up the new VPS and install the stack

Before you move any data, the new VPS must run the same software stack your WordPress site expects. The following commands install nginx, MariaDB, PHP 8.3, and the required PHP extensions on Ubuntu 24.04:

sudo apt update && sudo apt upgrade -y
sudo apt install nginx mariadb-server php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-xml php8.3-mbstring php8.3-zip php8.3-imagick php8.3-bcmath -y

After installation, start both services and enable them to boot automatically:

sudo systemctl enable --now nginx mariadb php8.3-fpm

Then secure the MariaDB installation:

sudo mysql_secure_installation

Follow the prompts: set a root password, remove anonymous users, disallow remote root login, and remove the test database. This is the same prompt you answer on any fresh MariaDB install, it is not specific to WordPress.

Finally, create an empty database and a dedicated user for the migration. Replace wpsite, wpuser, and strongpassword with your own values:

sudo mysql -u root -p
CREATE DATABASE wpsite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON wpsite.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Step 2, Take a full backup from the old host (zero downtime so far)

Your current site is still live. Connect to the old shared hosting server via SSH. The first backup is a full dump of the files and the database. Run these commands in a temporary directory on the old server (usually /tmp or your home folder):

mkdir ~/wp-backup
cd ~/wp-backup
mysqldump -u DB_USER -p DB_NAME > db.sql
tar -czf files.tar.gz /path/to/your/wordpress/

Replace DB_USER and DB_NAME with the values from your wp-config.php file. The database password will be prompted interactively. If your host restricts mysqldump over remote connections, use phpMyAdmin to export the SQL file and upload it via SCP, less elegant but works.

You now have a portable snapshot. Transfer both files to the new VPS:

scp db.sql files.tar.gz root@NEW_VPS_IP:~/

On the new VPS, extract and import:

cd ~
tar -xzf files.tar.gz
sudo mysql -u root -p wpsite < db.sql

Move the WordPress files to the web root. The default nginx document root on Ubuntu is /var/www/html:

sudo mv /path/to/wordpress/* /var/www/html/

At this point you have an exact copy of your site running locally on the new VPS, but it is not yet serving public traffic. The only thing missing is the final delta of changes made since the backup.

Step 3, DNS preparation: reduce TTL before cutover

This is the step most migration guides skip and most site owners regret skipping. DNS records have a Time-To-Live (TTL) that tells resolvers how long to cache the record. A default TTL of 3600 seconds (1 hour) or 14400 seconds (4 hours) means that after you change the A record, some visitors will still hit the old server for up to that many seconds.

At least 48 hours before you plan the cutover, reduce the TTL of your domain's A record to 60 or 120 seconds. This change tells every DNS resolver worldwide to re-check after two minutes instead of several hours. The reduced TTL does not make your site slower, it just forces more frequent lookups during the window you are migrating.

How you do this depends on your DNS provider (Cloudflare, AWS Route 53, VNPT's DNS, the registrar's panel). Navigate to the A record for your domain (or www subdomain), edit the TTL field, set it to 60 (or 120 if 60 is not offered), and save.

Step 4, The cutover: rsync the final delta and swap DNS

When you are ready to flip the switch (ideally during a low-traffic window), run the final rsync to copy only the files that changed since your initial backup. Run this from the new VPS, pulling the latest changes:

sudo rsync -avz --delete \
  USER@OLD_HOST_IP:/path/to/wordpress/ \
  /var/www/html/

The --delete flag removes any files on the destination that no longer exist on the source, important if you deleted unused plugins or themes on the old server. Run it again a minute later to catch any final writes. By the second run the delta should be very small (a few KB or empty).

Now repeat the database sync. Lock the tables on the old server so no writes occur after the dump:

# On old host:
mysql -u DB_USER -p DB_NAME -e "FLUSH TABLES WITH READ LOCK;"
mysqldump -u DB_USER -p DB_NAME > /tmp/final-db.sql
mysql -u DB_USER -p DB_NAME -e "UNLOCK TABLES;"

Copy the final SQL file and import it on the new VPS:

scp OLD_HOST:/tmp/final-db.sql ~/
sudo mysql -u root -p wpsite < ~/final-db.sql

The database on the new VPS now matches the old server exactly, up to the second of the lock. The site is still running on the old host at this instant, but every piece of data now lives on the new VPS.

Now flip the DNS A record, change the IP from the old shared hosting IP to the new VPS's dedicated IPv4. If you reduced the TTL beforehand, the change propagates within minutes. While waiting, verify the new server works by point your local /etc/hosts file at the new IP:

echo "NEW_VPS_IP yourdomain.com www.yourdomain.com" >> /etc/hosts

Then visit https://yourdomain.com in your browser, the site should load identically. If it does, remove the /etc/hosts entry and wait for the DNS change to propagate to your own resolver.

Step 5, Verify everything and shut down the old host

After the DNS change propagates (typically 10 to 30 minutes with a 60‑second TTL), run these checks from a machine outside your network or a cloud shell:

dig +short yourdomain.com
# Should return the NEW VPS IP

curl -I https://yourdomain.com
# Should return HTTP/2 200

If the old host still responds to requests after an hour, you may have a hostname configured in WordPress that points to the old IP. Check wp-config.php and the wp_options table (siteurl, home) on the new VPS. If the old server still logs hits, you can leave it running for another 48 hours as a safety net, but after that the old hosting account can be canceled.

Troubleshooting common issues

"The site is showing a blank white screen (WSOD)"

This is almost always a PHP 8.3 compatibility issue. A plugin or theme that ran fine on PHP 7.4 may throw a fatal error on a newer version. Enable PHP error display temporarily by editing /etc/php/8.3/fpm/php.ini and setting display_errors = On, then reload PHP-FPM. The error message tells you which file and line to fix. Common fixes: replace deprecated mysql_* functions, update the theme, or disable the offending plugin from the command line with wp plugin deactivate PLUGIN_NAME (requires WP-CLI).

"Mixed content warnings (HTTP images on HTTPS site)"

WordPress stores absolute URLs in the database. If the old site used HTTP and the new server enforces HTTPS, many internal URLs are still http://. Run a search-replace with WP-CLI or use a plugin like Better Search Replace. The safest method is WP-CLI because it also serializes properly:

sudo -u www-data wp search-replace 'http://olddomain.com' 'https://newdomain.com' --path=/var/www/html

If you keep the same domain name, replace http:// with https://.

"MySQL connection errors, 'too many connections' or 'Access denied'"

The new MariaDB install likely uses a default connection limit of 151, which is fine for most WordPress sites. If your site uses object caching or connects from multiple application servers, increase max_connections in /etc/mysql/mariadb.conf.d/50-server.cnf and restart MariaDB. For the "Access denied" error, double-check the database user and password in wp-config.php match what you created in Step 1.

FAQ

How long does a WordPress VPS migration take in practice?

The initial backup and rsync can take 15 to 30 minutes for a 5 GB site. The cutover itself (final rsync + DNS swap) takes about 5 minutes. Total time from starting the VPS setup to serving traffic from the new host: roughly 45 minutes for someone who is familiar with the commands.

Do I need to change the TTL on every DNS record?

Only the A record(s) and the CNAME record for www if you use a subdomain. MX, TXT, and NS records are not affected by a server move unless you also change mail providers. Focus on the records that point to your web server IP.

What happens to email if I migrate the site?

If your domain's MX records point to a separate mail provider (Google Workspace, Zoho, the shared hosting mail server), mail is unaffected, the web server move does not touch MX. If your WordPress site uses SMTP via a plugin like WP Mail SMTP or FluentSMTP, re-configure the SMTP credentials on the new VPS; the outbound traffic will come from the new IP, which may affect sender reputation. For a self-hosted SMTP server on the VPS, run warm-up for the new IP before sending bulk mail.

Can I keep the old host running as a fallback?

Yes, and many admins do this for 24 to 48 hours. Keep the old hosting account active with a read-only copy of the site. If DNS propagation reveals an issue with the new server, you can flip the A record back to the old IP within minutes. After 48 hours without error, cancel the old account.

Does the migration work the same for WooCommerce or membership sites?

Yes, the process is identical, files and database. The only extra step is to put the WooCommerce site into maintenance mode on the old server during the final export (wp maintenance-mode activate) to prevent orders or user registrations from being written after the final SQL dump. Reactivate after you confirm the new server accepts data.

Why choose a Vietnam VPS for WordPress?

If your users are in Vietnam, a Vietnam VPS with a dedicated IPv4 keeps traffic within Viettel, VNPT, or FPT Telecom (the three largest domestic ISPs and data center operators in Vietnam), avoiding the latency of routing through Singapore or Hong Kong. Email sent from a Vietnamese IP to Vietnamese free mail providers (Zalo Mail, VNPT Mail, Viettel Mail) lands faster and is less likely to be flagged as foreign spam. The VPS sits inside a Tier 3 data center with 99.9% uptime, the same infrastructure that host government and banking workloads in the country.

Related articles

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.

把WordPress从共享主机迁移到VPS

迁移的关键在DNS TTL和切换顺序,而不是复制文件本身。文中给出零停机切换的完整步骤和回滚方案。按顺序执行可以把风险降到最低。