How to Push WordPress Staging to Live Safely
Pushing staging to live is where migrations go wrong. Pre-push checklist, host-native push tools, manual WP Migrate DB method, and post-push verification.
Pushing a staging environment to live is one of those tasks that looks straightforward until it isn't. The URL changes, serialised data in the database still points to your staging domain, caching layers serve stale content, and suddenly your live site is half-broken three minutes after the push.
The process itself isn't complicated. The failures happen when steps are skipped — no backup before the push, no URL find-replace after, no post-push verification. This guide covers the pre-push checklist, three push methods ordered from safest to most manual, and the post-push checks that catch the mistakes before your client does.
Pre-push checklist
Run through this before touching anything. These aren't suggestions — each item corresponds to a real failure mode.
- Back up the live site first. Manually trigger a backup right now, even if you have automated backups running. You want a restore point from minutes ago, not hours ago.
- Note the live database prefix. If your live site uses
wp_and your staging useswpstg_, a full DB overwrite will need the prefix corrected, or all your existing tables become orphaned. - Verify plugin versions match. Staging should mirror live exactly. A plugin version mismatch can cause database schema conflicts after a DB push.
- Test all forms on staging. Contact forms, checkout, login, password reset. If they're broken on staging, they'll be broken on live after the push.
- Disable caching plugins before the push. Cached pages from staging with the staging URL in them should not land on your live server. Deactivate WP Rocket, LiteSpeed Cache, or whatever you're using before initiating the push.
- Confirm staging is set to noindex. Go to Settings > Reading on staging and verify "Discourage search engines from indexing this site" is checked. You do not want to push with this setting accidentally left on live — and you want to make sure you haven't accidentally turned it off on staging and accumulated staging URLs in Google's index.
- Check image paths. If images are hardcoded to
https://staging.yourdomain.com/wp-content/uploads/, the URL find-replace during migration will catch these — but verify the find-replace ran correctly after the push. - Test WooCommerce checkout if applicable. Place a test order on staging with a test payment method. Verify order confirmation emails send. After the push, repeat the same test on live before announcing the deploy.
- Lower DNS TTL if switching hosts. If this push involves a host migration, lower your DNS TTL to 300 seconds (5 minutes) at least 24 hours before the push. This shortens the propagation window if you need to roll back.
- Have a rollback plan. Know exactly what you'll do if something breaks. Restore backup from step 1? Revert to a previous WP Engine checkpoint? Having the plan written down prevents scrambling under pressure.
Method 1 — Host-native push (recommended)
If your host provides a staging push tool, use it. These tools handle the URL replacement, handle the database connection switching, and often purge the CDN cache automatically. The failure rate is significantly lower than manual pushes.
Kinsta (MyKinsta):
Navigate to MyKinsta > Sites > Your Site > Staging. Click "Push to Live." Kinsta offers selective push — you can push the database only, files only, or both. This matters when you've made database changes on staging but want to keep live file changes, or vice versa. After the push, Kinsta automatically purges the Cloudflare CDN cache. The staging environment remains intact so you can compare if something looks wrong.
WP Engine:
WP Engine uses the same selective push concept. From the User Portal, go to your staging environment and click "Push to Production." You can choose to push files, database, or both. WP Engine also lets you exclude specific directories from the file push — useful for protecting the wp-content/uploads/ folder on live if you haven't synced media separately.
Cloudways:
In the Cloudways dashboard, navigate to your application > Staging Management. Click the "Push to Live" button. Cloudways pushes both files and database together — there's no selective push option. Make sure your staging environment is a full copy of what you want live before initiating. The push creates a backup of the live environment automatically before overwriting it.
The reason host-native tools are safer isn't magic — it's that they run the URL replacement as part of the push process, handle the database connection strings correctly, and have been tested against the specific server environment you're running on. When you do it manually, you're recreating that logic from scratch.
Method 2 — WP Migrate DB Pro
WP Migrate DB Pro is the best option for pushing between sites on different hosts, or when you want fine-grained control over what gets migrated.
Setup:
Install WP Migrate DB Pro on both your staging and live sites. On the live site, go to WP Migrate DB Pro > Settings and enable the "Accept push requests" option. Copy the connection key shown there.
On staging, go to WP Migrate DB Pro > Migrate > Push. Enter the live site URL and paste the connection key. The plugin will establish a connection between the two sites.
Running the migration:
In the Push settings, configure your find-replace rules. The plugin will pre-populate https://staging.yourdomain.com → https://yourdomain.com based on the site URLs you've entered. If your staging site uses a different subdomain or a completely different domain (common with WP Engine's wpengine.com staging URLs), add that as a separate find-replace rule.
The critical feature here is that WP Migrate DB Pro handles serialised data correctly. WordPress stores many option values, widget settings, and theme configurations as PHP-serialised strings. A naive find-replace (running SQL REPLACE() directly in phpMyAdmin) breaks serialised arrays because the string length metadata is no longer accurate. WP Migrate DB Pro unserialises, replaces, and re-serialises these values so the data integrity is preserved.
What the free version can't do:
The free version of WP Migrate DB only supports pull operations (pulling from a remote site to local) and does not support push. If you're working on a budget, you can export from staging and import to live manually, then run WP-CLI search-replace — but that's Method 3 territory.
Method 3 — Manual push
The manual method gives you complete control and costs nothing beyond your time. It's also where most staging pushes go wrong, so follow the steps exactly.
Step 1: Sync files
Use rsync to push files from staging to live. If you have SSH access to both servers:
rsync -avz --exclude='wp-config.php' \ /path/to/staging/wp-content/ \ user@liveserver:/path/to/live/wp-content/
Exclude wp-config.php — the live site has its own database credentials. If you're pushing a theme or plugin update only, scope rsync to just that directory rather than the entire wp-content/ folder.
Step 2: Export the staging database
wp db export staging-backup.sql --allow-root
Or via phpMyAdmin: select all tables, export as SQL with "Add DROP TABLE" option checked.
Step 3: Import to live
wp db import staging-backup.sql --allow-root
Or via phpMyAdmin on your live server: import the SQL file.
Step 4: Run search-replace
This is the step people skip and then spend an hour debugging broken links.
wp search-replace 'https://staging.yourdomain.com' 'https://yourdomain.com' \ --all-tables \ --precise \ --report-changed-rows
The --precise flag is critical. It tells WP-CLI to use PHP-based replacement rather than SQL REPLACE(), which handles serialised data correctly. The --report-changed-rows flag shows you exactly what was updated so you can verify the replacement ran across the tables you expected.
If your staging site uses a subdomain on your live domain (e.g., staging.yourdomain.com) and live is yourdomain.com, also run a replace for the siteurl and home options specifically to double-check:
wp option get siteurl wp option get home
Step 5: Flush permalinks and clear object cache
wp rewrite flush wp cache flush
Then log into the WordPress admin and go to Settings > Permalinks and click Save Changes, even if nothing changed. This regenerates the .htaccess rewrite rules against the live site's structure.
Post-push checklist
The push completed — now verify before anyone else visits the site.
- Flush all caches. Page cache (WP Rocket, LiteSpeed Cache, etc.), object cache (Redis flush via WP-CLI:
wp cache flush), and CDN cache (purge from your CDN dashboard or via the WordPress plugin if it supports it). - Test the homepage. Does it load? Is the URL correct in the browser? Are images rendering?
- Test three internal links. Click through to an inner page, a category page, and a tag or archive page. Verify URLs are not pointing to staging.
- Test checkout or the primary contact form. Place a test order using a test payment token. Submit the contact form and verify the notification email arrives at the correct address.
- Check the SSL certificate. Is the padlock present? Is HTTPS forced? If you see a certificate warning, check whether the SSL certificate on live is valid and whether
FORCE_SSL_ADMINis set correctly inwp-config.php. - Verify staging is still noindexed. Log back into staging and confirm Settings > Reading still has the noindex option checked. It's easy to have accidentally unchecked this during development.
- Check Search Console after 24 hours. Log into Google Search Console and look for a spike in crawl errors or a coverage drop. A new batch of 404s after a push usually means either URL structure changed or the search-replace didn't catch all the staging URLs.
Common mistakes that break staging pushes
Serialised data with the wrong URL. This is the number one cause of broken staging pushes when done manually. If you ran a search-replace via phpMyAdmin's SQL tab using a raw REPLACE() function, you've broken the serialised strings. The symptom is settings reverting to defaults, widgets disappearing, or the site URL in wp_options looking correct but the site still redirecting to staging. Fix: run wp search-replace with --precise flag on all tables.
Caching plugins storing staging URLs in the live database. Some caching plugins write their configuration (including cached URLs and CDN origin URLs) directly to the database. If you pushed the database from staging, those settings now point to your staging domain. After any push, go into your caching plugin settings and reset the CDN URL and cache origin manually.
Mismatched PHP versions. Your staging server runs PHP 8.2, your live server runs PHP 7.4. After a push, PHP 8.2-specific syntax in custom code will throw fatal errors on live. Check php version parity before any push with php -v on both servers.
Hardcoded staging URLs in theme options or Customizer. Theme options panels, the Customizer, and many page builder settings store URLs as plain strings that wp search-replace will catch — but only if you included --all-tables. Without that flag, WP-CLI only replaces the core WordPress tables, and custom theme option tables are missed.
Related reading
// new_articles
Get notified when new guides drop
Practical WordPress guides from a working agency owner. No filler. Unsubscribe any time.
Was this article helpful?
Thanks for the feedback!