WordPress & Web Development Basics
How to Migrate a Local WordPress Site to a Live Server Without Breaking Anything

Photo by Pexels — moving a site from local to live is really about moving between two very different environments like this one.
The first time I moved a WordPress site from my laptop to a live server, I did it at 11 p.m. the night before a client's product launch, because I'd promised it would "just take twenty minutes." It took four hours. The homepage loaded fine. Every other page redirected back to localhost. Images were broken. The contact form silently ate every submission. None of it was because WordPress is fragile — it was because I didn't understand what a migration actually moves, and what it quietly leaves behind.
That night taught me more about how WordPress actually works than any tutorial had. This guide is the version of that lesson I wish someone had handed me first: what a local-to-live migration really involves, three different ways to do it depending on your comfort level, and the exact list of things that break — and why — so you can catch them before your visitors do.
Quick answer: Migrating a local WordPress site to a live server means moving three things — your files (theme, plugins, uploads), your database (posts, settings, users), and your site's URL references inside that database. The safest approach for beginners is a migration plugin like Duplicator or All-in-One WP Migration, which packages everything and handles the URL replacement automatically. Developers comfortable with SFTP and phpMyAdmin often prefer the manual method for more control. Either way, always test the live copy on a temporary URL before pointing your domain at it.
What's in this guide
- Why WordPress migrations break sites (it's not what you'd guess)
- Before you touch anything: the pre-migration checklist
- Method 1: Manual migration with SFTP and phpMyAdmin
- Method 2: Migration with a plugin (Duplicator / All-in-One WP Migration)
- Method 3: Using your host's built-in migration or staging tool
- Which method should you actually use?
- Going live: DNS, propagation, and the switch-over
- Troubleshooting: the seven things that break after migration
- Post-migration checklist
- Frequently asked questions
Why WordPress migrations break sites (it's not what you'd guess)
Most people assume a WordPress migration is just "copy the files somewhere else." That assumption is exactly what caused my four-hour night. Files are only half the site. The other half — and the half that actually causes almost every migration headache — lives inside the MySQL database, and it's tied to your site's URL in a way that isn't obvious until it bites you.
Here's the part that surprises most beginners: WordPress doesn't just use your site URL for navigation links. It bakes that URL directly into the database, inside a special PHP format called serialized data. Page builders like Elementor, Divi, and Beaver Builder store entire layout configurations as serialized arrays, and many of those arrays include absolute URLs — not relative ones. Widgets do the same. So does the Customizer.
Serialized PHP data looks something like this, where the number before each string is a character count WordPress relies on to read the data correctly:
a:2:{s:3:"url";s:20:"http://localhost/mysite";s:5:"title";s:9:"Home Page";}Now imagine you open your database export in a plain text editor and do a simple find-and-replace, swapping http://localhost/mysite for https://realsite.com. The text changes, but the character count baked into the string — that s:20 — no longer matches the new, different-length URL. WordPress tries to read that data, the count doesn't line up, and it silently discards the whole field. This is precisely why plain text-editor find-and-replace is the single most common cause of a broken page builder layout after migration, and why serialization-aware tools exist in the first place.
Once you understand that one mechanic, the rest of this guide makes a lot more sense. Every method below exists to solve the same underlying problem: moving files is easy, but rewriting URLs inside serialized data safely is the part that actually requires care.
wp-content/uploads folder, which holds every image, PDF, and media file as real files on disk — not database entries; and (3) the MySQL database itself, with every URL reference inside it correctly rewritten.Before you touch anything: the pre-migration checklist
Fifteen minutes of preparation here will save you an evening of debugging later. Before you export a single file, confirm the following.
Pre-migration checklist
- You know your live server's PHP version, and it's the same or newer than your local environment's version
- You have SFTP (or FTP) credentials for the live host, or access to a file manager in the hosting control panel
- You have live database credentials, or the ability to create a new database and user through your host's control panel
- Your local site is fully working — no broken links, no plugin errors, images loading correctly — before you migrate a copy of a broken site
- You've decided on a temporary URL to test the live copy on (a staging subdomain, or a temporary IP/folder address) before pointing your real domain at it
- You have a full local backup saved somewhere outside your local machine, in case something goes wrong on either end
That last point matters more than it sounds. I've seen developers migrate a site, run into trouble on the live server, then discover their only working local copy had already been half-overwritten by a sync tool. Keep a separate, untouched backup zipped and sitting in cloud storage until the live site has been running cleanly for at least a week.

Photo by Pexels — a five-minute checklist prevents most of the migration disasters people post about in support forums.
Method 1: Manual migration with SFTP and phpMyAdmin
This is the method I now use for almost everything, once I finally understood what was going wrong that first night. It takes longer to learn but gives you complete visibility into every step, and it works on hosts that restrict which plugins you can install before the site is even live.
Step 1: Export the database
In your local environment (Local, XAMPP, MAMP, or DevKinsta), open phpMyAdmin. Select your WordPress database from the sidebar, click the Export tab, choose the Quick export method with the SQL format, and click Go. This downloads a single .sql file containing every post, page, comment, setting, and user in your database.
Step 2: Copy your files
Connect to your local site's file system and copy the entire WordPress installation, or at minimum these three things: the wp-content folder (themes, plugins, and uploads all live here), and the root-level wp-config.php file for reference — you won't reuse it directly, but you'll need to compare settings. Zip wp-content for a faster transfer.
Step 3: Set up the database on the live server
In your hosting control panel (cPanel, Plesk, or your host's custom dashboard), create a new MySQL database and a database user with full privileges on it. Write down the database name, username, password, and host — usually localhost on shared hosting, but check your host's documentation, since some managed hosts use a different value.
Step 4: Import the database
Open phpMyAdmin on the live server, select the new empty database, click Import, choose your .sql file, and run the import. Large files sometimes exceed the upload limit set in phpMyAdmin — if that happens, compress the file to a .zip first, since most phpMyAdmin installs accept compressed SQL imports at a larger effective size.
Step 5: Upload your files over SFTP
Using an SFTP client such as FileZilla or Cyberduck, connect to your live server and upload a fresh copy of WordPress core files (or use the one-click WordPress installer many hosts provide), then upload your wp-content folder on top of it, overwriting the default theme and plugin folders.
Step 6: Update wp-config.php
Edit the live server's wp-config.php file and update these four lines with the database details you created in Step 3:
define( 'DB_NAME', 'your_live_database_name' );
define( 'DB_USER', 'your_live_database_user' );
define( 'DB_PASSWORD', 'your_live_database_password' );
define( 'DB_HOST', 'localhost' );Step 7: Run a serialization-safe search and replace
This is the step that fixes the character-count problem explained earlier. If you have SSH access, WP-CLI's built-in command handles it correctly in one line:
wp search-replace 'http://localhost/mysite' 'https://yourrealdomain.com' --all-tablesIf you don't have SSH access, install the free Better Search Replace plugin on the live site, enter your old local URL and new live URL, select all tables, and run it in dry-run mode first to preview exactly what will change before committing.
.sql file in a plain text editor and manually replace URLs with Find and Replace. It will corrupt every serialized field that contains your old URL, silently breaking page builder layouts, widget content, and theme customizer settings.Method 2: Migration with a plugin (Duplicator / All-in-One WP Migration)
If SFTP and phpMyAdmin sound like more than you want to deal with, a migration plugin does effectively the same seven steps above, but wraps them into a guided interface. I recommend this route to anyone migrating a site for the first time, or anyone who just wants it done reliably without becoming a database expert along the way.
Using Duplicator
- Install and activate the free Duplicator plugin on your local WordPress site.
- Go to Duplicator → Packages → Create New, and follow the wizard. It scans your site for potential issues before building the package.
- Once built, download two files: the Installer (a PHP file) and the Archive (a zip containing your files and database).
- Upload both files to the root directory of your live server via SFTP or your host's file manager.
- Visit
yourdomain.com/installer.phpin a browser. Duplicator's wizard will detect the archive, ask for your new database credentials, and handle the URL search-and-replace automatically using a serialization-safe method. - Once the installer finishes, delete
installer.phpfrom the server immediately — leaving it there is a real security risk, since anyone who finds the URL could theoretically re-run parts of the installation process.
Using All-in-One WP Migration
This plugin works similarly but exports everything into a single proprietary file format. Install it on your local site, go to All-in-One WP Migration → Export, choose "File" as the export destination, and download the resulting file. On the live server, install the same plugin, go to Import, and upload the file. One caveat worth knowing before you rely on it: the free version caps export size around 512MB, which is plenty for most brochure and blog sites, but tight for large media libraries or WooCommerce stores with years of order history — you'd need the paid extension for unlimited size in that case.

Photo by Pexels — plugin-based migration still benefits from a quick look at your theme and plugin files before you package everything up.
Method 3: Using your host's built-in migration or staging tool
Many managed WordPress hosts — Kinsta, WP Engine, Flywheel, and SiteGround among them — include a staging environment and, in some cases, a direct site migration tool in their dashboard. If your host offers this, it's often the least error-prone path, because the host controls both the staging and production environment and has already handled the URL-rewriting logic for you.
The general pattern looks like this: create a staging site from your dashboard, upload or connect your local site's files and database to that staging environment (some hosts provide a free migration plugin built specifically for their platform), verify everything works on the staging URL, and then use the host's one-click "push to live" or "deploy" button. Because the host built the tool around its own infrastructure, edge cases like custom caching layers or CDN configuration are usually already accounted for.
The tradeoff is flexibility. Host-specific tools work beautifully within that host's ecosystem but generally can't help you migrate a local site to a host that doesn't offer one, and they don't teach you the underlying mechanics the way the manual method does. If you're planning to work with WordPress regularly, I'd still suggest doing the manual method once, even on a throwaway test site, just to understand what's actually happening under the hood.
One more thing worth knowing before you commit to a host-specific tool: read the fine print on what exactly gets carried over. Some hosts migrate the database and files but skip server-level configuration like custom PHP settings, cron jobs, or redirect rules you'd set up in an .htaccess file. If your local site relies on any of those, check for them manually on the new server after the automated migration finishes, rather than assuming the tool caught everything.
Which method should you actually use?
| Method | Best for | Time needed | Learning curve |
|---|---|---|---|
| Manual (SFTP + phpMyAdmin) | Developers, agencies, hosts with no plugin support pre-launch | 40–90 minutes | Steep at first, then fastest long-term |
| Migration plugin (Duplicator, AIOWM) | First-time migrators, freelancers, small business sites | 20–40 minutes | Low — guided wizard |
| Host's built-in tool | Sites already on managed hosts like Kinsta, WP Engine, SiteGround | 15–30 minutes | Very low, but host-specific |
My honest recommendation: if this is your first migration, use a plugin. It removes the two most common failure points — forgetting to migrate the uploads folder, and corrupting serialized data — because the plugin handles both automatically. Once you've done two or three migrations and want more control, or you're troubleshooting a migration that went wrong, learning the manual method pays off immediately.
Going live: DNS, propagation, and the switch-over
Here's the part that catches people off guard even after a flawless migration: your domain's DNS records don't update instantly. When you change your domain's A record to point at the new server's IP address, that change has to propagate across DNS servers worldwide, which can take anywhere from a few minutes to 48 hours, though most changes today settle within one to four hours thanks to shorter default TTL (time-to-live) values.
To avoid a gap where visitors see a broken or half-migrated site, follow this order:
- Build and fully test the site on the live server first, using either a staging subdomain or a temporary URL your host provides (often something like
yourdomain.hostingcompany.com). - Test everything on that temporary URL: forms, checkout flows if applicable, page load speed, and mobile responsiveness.
- Lower your domain's DNS TTL to 300 seconds (5 minutes) at least 24 hours before the planned switch-over, if you can access your DNS settings in advance. This makes the eventual propagation much faster.
- Update the A record to point at the new server, then wait and periodically check propagation using a DNS checker tool.
- Keep the old local or staging copy alive for a week after go-live as a fallback, without deleting anything, in case you spot an issue after traffic starts flowing to the new server.
hosts file to point your domain temporarily at the new server's IP — only on your machine, without affecting anyone else's DNS resolution.If you're migrating an existing live site rather than launching a brand-new one, there's an extra layer of caution worth adding: schedule the switch-over for your lowest-traffic hours, and let anyone who manages email or third-party integrations know in advance. MX records for email are separate from the A record that points to your website, so email delivery usually isn't affected by a site migration — but it's still worth confirming your mail settings weren't accidentally touched if you're moving hosts entirely rather than just moving the site within the same hosting account.
Troubleshooting: the seven things that break after migration
Even a careful migration occasionally throws up one of these. Here's what each one usually means and how to fix it.
1. White screen of death
Usually a PHP memory limit that's too low on the new server, or a plugin incompatible with the live PHP version. Add define('WP_DEBUG', true); to wp-config.php temporarily to reveal the actual error instead of a blank page, then remove it once fixed — leaving debug mode on publicly is a security risk.
2. Mixed content warnings (padlock missing or broken)
This happens when your site loads over HTTPS but some resources — usually images or scripts referenced with an absolute http:// URL — still load over plain HTTP. Run your serialization-safe search-and-replace again, this time swapping any remaining http:// references for https://.
3. Every page except the homepage returns a 404
Your permalink structure needs to be re-saved on the new server so WordPress regenerates the .htaccess rewrite rules. Go to Settings → Permalinks and click Save, without changing anything, and the 404s typically disappear immediately.
4. Images show broken icons
The wp-content/uploads folder wasn't fully transferred, or file permissions on the new server are too restrictive. Confirm the folder made it across intact, and set folder permissions to 755 and file permissions to 644 if your host requires it.
5. Login redirect loop
Usually caused by a caching plugin or object cache still referencing the old URL, or conflicting WP_HOME and WP_SITEURL constants in wp-config.php. Clear all caching plugin settings and confirm those two constants, if present, match your new live URL exactly.
6. "Error establishing a database connection"
Almost always incorrect database credentials in wp-config.php, or a database host value that differs from what your live host expects. Double-check the four DB constants from Step 6 of the manual method above.
7. Contact forms stop sending emails
Local development environments often fake email sending, so a form that "worked" locally may never have actually sent anything. On the live server, install an SMTP plugin like WP Mail SMTP and connect it to a real email provider, since most hosting servers' default PHP mail function is unreliable and frequently lands in spam.

Photo by Pexels — once the site is live, a short round of testing on the actual server catches issues no local environment can predict.
Post-migration checklist
Run through this within the first hour of going live
- Visit every main navigation page and confirm it loads without errors
- Click through at least one form and confirm the email arrives
- Check that images load on both desktop and mobile view
- Confirm the site loads over HTTPS with no mixed content warnings
- Re-save Permalinks under Settings to regenerate rewrite rules
- Update your XML sitemap and resubmit it in Google Search Console
- Set up or confirm your backup plugin is running on the new server
- Remove any leftover installer files (Duplicator's installer.php, for example)
- Verify SSL certificate is active and auto-renewing on the new host
- Update any hardcoded old-domain links in your site's header, footer, or menus
That sitemap resubmission step is easy to forget and genuinely matters. If your migration changed anything about the URL structure, Google's cached version of your sitemap may still point search crawlers at outdated paths, which can slow down re-indexing of your live site for days or weeks longer than necessary.
Frequently asked questions
Can I migrate a WordPress site without a plugin?
Yes. You can migrate manually by exporting the database with phpMyAdmin or WP-CLI, uploading the wp-content folder and core files over SFTP, updating the wp-config.php database credentials, and running search-and-replace on the site URL. It takes longer than a plugin but gives you full control and works even on hosts that block plugin installs during setup.
Why does my live site show the wrong URLs after migration?
WordPress stores the site URL in the database in multiple places, including inside serialized PHP arrays used by page builders and widgets. A plain find-and-replace in a text editor corrupts serialized data. Use a serialization-aware search-and-replace tool such as WP-CLI's search-replace command or the Better Search Replace plugin instead.
How long does a WordPress migration usually take?
A small brochure site with a handful of pages typically takes 20 to 40 minutes end to end. A larger site with tens of thousands of posts, a big media library, and several plugins can take one to three hours, mostly due to database export size and DNS propagation waiting time.
Will my site go down while I migrate it?
Not if you do it correctly. You build and test the site on the live server or a staging subdomain first, confirm everything works, and only then point the domain's DNS or update the live URL. Visitors keep seeing the old site right up until the switch happens.
Do I need to migrate the uploads folder separately from the database?
Yes. The database stores post content and settings, but actual image, PDF, and video files live in wp-content/uploads as physical files on disk. You must transfer both the database export and the full uploads folder, or your posts will display with broken image icons.
What causes a white screen after migrating WordPress?
A white screen after migration is almost always a PHP memory limit error, a plugin incompatible with the live server's PHP version, or incorrect database credentials in wp-config.php. Enable WP_DEBUG temporarily to see the actual error message instead of a blank page.
Migrating a WordPress site stops being scary once you understand that you're really moving three separate things — files, a database, and a set of URL references buried inside that database — rather than one single "site." Pick the method that matches your comfort level, work through the checklists above in order, and test on a temporary URL before your domain ever points at the new server. Do that, and your migration should take a fraction of the four hours mine did.