Hướng dẫn · 19/09/2026

How to Migrate WordPress to New Hosting Without Downtime

The difficult part of moving WordPress is not copying files; it is avoiding lost orders, comments, or content created during the move. A reliable migration needs a rollback path, tests on the new server before DNS changes, and control over the period when both servers exist.

Hướng dẫn chuyển WordPress sang hosting mới không downtime

The difficult part of moving WordPress is not copying files; it is avoiding lost orders, comments, or content created during the move. A reliable migration needs a rollback path, tests on the new server before DNS changes, and control over the period when both servers exist.

This guide covers a single WordPress site that keeps the same domain. Multisite, high-traffic WooCommerce, or systems with several writers need a tailored plan and a staging rehearsal.

Goals and principles

  • The public site remains reachable through most of the process.
  • The new server is tested before receiving real traffic.
  • The final write freeze is short and clearly communicated.
  • The old server remains intact long enough for rollback.
  • Temporary secrets, backups, and accounts are removed afterward.
DNS does not move every visitor at once. During cache expiry, some requests may reach the old server while others reach the new one.

1. Inventory the current site

Record PHP, MySQL/MariaDB, WordPress, web server, PHP extensions, cron jobs, file/database size, and email configuration. Identify cache, security, backup, object-cache, CDN, payment, and webhook integrations.

wp core version
wp plugin list
wp theme list
wp db size
wp cron event list

Confirm that the destination supports the required PHP version and extensions. Check upload, memory and execution limits, cron, SSL, file permissions, and outbound mail. Avoid upgrading WordPress, PHP, and plugins during the hosting migration; too many simultaneous changes make failures harder to diagnose.

2. Lower DNS TTL before cutover day

Lower web-record TTL to about 300 seconds 24–48 hours beforehand if the DNS provider permits it. Existing caches do not disappear immediately; the previous TTL must expire first.

Inventory the complete zone before changing nameservers or records: A, AAAA, CNAME, MX, SPF, DKIM, DMARC, and verification records. If only the website moves, preserve email records. A stale AAAA record can keep IPv6 users on the old server after the A record changes.

3. Create and verify backups

Back up both the database and all WordPress files. Include uploads, plugins, themes, mu-plugins, .htaccess, Nginx/Apache configuration, and cron jobs outside WordPress.

wp db export ~/backup/site-pre-migration.sql
tar -czf ~/backup/site-files.tar.gz \
  --exclude='wp-content/cache' \
  /var/www/example.com

Store backups away from the source server, encrypt sensitive data, and verify that archives can be read. Ideally, restore them into a temporary environment. An untested backup is only an assumption.

4. Prepare the new hosting environment

Create the virtual host, database, and least-privileged database user. Install the matching runtime, enable HTTPS, and configure redirects without changing DNS yet. When the domain does not point to the destination, use a DNS challenge or a temporary certificate according to provider capabilities.

Copy files with a tool that preserves timestamps and permissions. Over SSH, rsync supports efficient repeated synchronization:

rsync -aH --delete \
  --exclude='wp-content/cache/' \
  user@old-server:/var/www/example.com/ \
  /var/www/example.com/

Treat --delete carefully: perform a dry run and verify source and destination first. Do not copy cache, sessions, or old backups unless needed.

5. Import the database and update configuration

wp db import ~/backup/site-pre-migration.sql
wp db check

Update DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST in wp-config.php. Never leave configuration files or SQL dumps in a web-accessible directory.

Keeping the same domain and path usually requires no URL replacement. When the domain or protocol changes, avoid blind SQL REPLACE() because WordPress stores serialized values. WP-CLI understands serialized data:

wp search-replace 'http://old.example' 'https://new.example' \
  --skip-columns=guid --dry-run

wp search-replace 'http://old.example' 'https://new.example' \
  --skip-columns=guid

Always run --dry-run first. Multisite requires different options and procedures; do not apply a single-site example unchanged.

6. Test before changing DNS

Edit the tester's hosts file so the real domain temporarily resolves to the destination IP. The browser sends the correct hostname, WordPress uses its real URL, and HTTPS/SNI behavior closely matches production.

203.0.113.20 example.com www.example.com

Flush the local DNS cache if necessary and use a private browser window. Only the modified computer sees the new host; visitors stay on the old server.

At minimum, test:

  • Home, posts, categories, search, and 404 pages.
  • Admin login/logout, media uploads, and post editing.
  • Contact forms, transactional email, CAPTCHA, and webhooks.
  • Cart, checkout, and payment callbacks in an appropriate test mode.
  • Permalinks, redirects, robots.txt, sitemap, and canonical URLs.
  • Images, CSS, JavaScript, fonts, and mixed content.
  • WP-Cron, system cron, queues, and backup jobs.
wp core verify-checksums
wp plugin status
wp rewrite flush
wp cache flush

Run wp rewrite flush only when needed and after web-server permalink rules are correct. Inspect PHP errors, web-server logs, and the browser console instead of judging only the home page.

7. Perform the final synchronization without data loss

For a site with occasional writes, enable a brief maintenance or read-only mode on the old server, stop cron and queues, export the final database, and synchronize recent uploads. For WooCommerce or memberships, this is the most important step.

  1. Announce a short maintenance window and temporarily block writes.
  2. Stop workers, WP-Cron, or webhook consumers on the old host.
  3. Export the final database.
  4. Synchronize new uploads and generated files.
  5. Import the final database on the new host.
  6. Clear caches, run smoke tests, and enable writes on the destination.

Do not run cron and queues on both servers simultaneously; emails, subscriptions, or jobs may execute twice. A site that cannot accept a maintenance window needs replication or a more advanced application-level synchronization design.

8. Switch DNS

Change A/AAAA records to the new IP, or update the load balancer according to the architecture. Keep the old configuration intact. Watch access logs on both hosts as traffic shifts.

dig +short example.com A
dig +short example.com AAAA
curl -I https://example.com

Check from several networks or resolvers, not just the hosts-file test computer. If a CDN or proxy is present, purge it carefully and confirm the new origin. Keep the old server read-only during DNS transition to avoid split data.

9. Monitor after cutover

For the first 24–72 hours, watch:

  • HTTP 4xx/5xx responses, PHP fatal errors, and slow queries.
  • CPU, RAM, disk, inodes, I/O, and database connections.
  • Logins, forms, orders, payments, and email delivery.
  • WP-Cron, queues, backups, and webhooks.
  • Certificate chains, HTTP-to-HTTPS redirects, and mixed content.
  • Traffic still reaching the old IP through long-lived DNS caches.

Once stable, restore the normal DNS TTL. Create a fresh backup from the new host and perform a small restoration test.

10. Plan the rollback

If a severe issue appears before the new host receives fresh data, point DNS back and reopen the old service. Once the destination has accepted orders or content, rollback is no longer a simple DNS change; newly created data must be reconciled.

Define rollback thresholds before cutover, such as error rate, failed checkout rate, or latency. Document the decision owner, DNS wait time, and treatment of new records. Keep the old server, database, and backups intact for several days or as compliance requires.

Clean up safely

After the observation period and once legitimate traffic no longer reaches the old host:

  • Revoke temporary SSH keys, accounts, and migration tokens.
  • Delete SQL dumps from web roots and temporary directories.
  • Disable old cron jobs and workers before canceling the old host.
  • Update infrastructure, monitoring, backup, and IP documentation.
  • Recheck file permissions: commonly 755 for directories and 644 for files, never blanket 777.
  • Rotate secrets if they passed through an unsafe channel.

Quick checklist

  1. Inventory runtimes, plugins, cron jobs, and integrations.
  2. Lower TTL 24–48 hours in advance.
  3. Back up files and database, then verify restoration.
  4. Build the destination and perform the initial copy/import.
  5. Test through the hosts file with the real domain.
  6. Briefly freeze writes and perform the final database/file sync.
  7. Switch DNS and monitor both servers.
  8. Keep the old host for rollback, then clean temporary secrets and backups.

Conclusion

A safe WordPress migration requires repeated synchronization and verification, not one copy followed by a DNS switch. A tested backup, hosts-file validation, controlled writes during the final sync, and a preserved rollback path substantially reduce the risk of data loss and service interruption.

References

Discussion

Comments 0

Sign in to comment

You need an account to join the discussion and reply to other readers.

Sign inRegister

No comments yet. Be the first to share your thoughts.