How-to · WordPress

Change WordPress URLs with wp search-replace

At the end every reference to the old address in the WordPress database (links in posts, settings, widgets and serialized plugin data) will point at the new address, and the home and siteurl settings will match.

Updated 4 Nov 20267 steps4 official sources
Before you start

What you need before step 1

Applies to: WordPress sites with WP-CLI, for domain changes, HTTP to HTTPS moves and staging to live moves (as documented on developer.wordpress.org)

Admin roles you need

  • SSH access to the server as the site's user, with WP-CLI installed
  • A database user that can update the WordPress database (the one in wp-config.php)

Licences

None needed.

Install instructions

WP-CLISee the install-wp-cli how-tohttps://make.wordpress.org/cli/handbook/guides/installing/Our step-by-step →Install steps

Reference documentation

wp search-replace referenceAll optionshttps://developer.wordpress.org/cli/commands/search-replace/Read

Also have ready

  • A fresh database backup taken immediately before you start
  • The exact old and new addresses, including https:// and with no trailing slash (for example https://old.contoso.com and https://contoso.com)
SiteGround web hosting
Step by step

7 steps

  1. 1

    Back up the database

    Where: SSH session, in the WordPress folder (the one containing wp-config.php)

    WordPress warns to make sure you have a database backup before changing URLs. Export it now.

    cd /var/www/contoso.com/public_html
    wp db export before-search-replace.sql
    You should see: Success: Exported to 'before-search-replace.sql'.
  2. 2

    Check the current home and siteurl

    Where: The same SSH session

    Note the current values so you know the exact string to search for.

    wp option get home
    wp option get siteurl
    You should see: Both print the old address, for example https://old.contoso.com.
  3. 3

    Run a dry run

    Where: The same SSH session

    --dry-run runs the whole operation and shows a report without saving changes. --skip-columns=guid leaves the GUID column alone; WordPress says never to change the contents of the GUID column. The command handles PHP serialized data, which a plain find-and-replace on an SQL file would break.

    wp search-replace 'https://old.contoso.com' 'https://contoso.com' --skip-columns=guid --dry-run
    You should see: A table of tables and columns with the number of replacements in each, and a summary line of replacements to be made. Nothing is changed yet.
  4. 4

    Decide whether you need --all-tables

    Where: The same SSH session

    By default the command only touches tables registered to WordPress with your table prefix. If plugins created their own tables that also hold the URL, add --all-tables-with-prefix (tables matching your prefix) or --all-tables (every table in the database, regardless of prefix). Run the dry run again with the flag to compare. On multisite, use --network for all sites or --url to target one.

    wp search-replace 'https://old.contoso.com' 'https://contoso.com' --skip-columns=guid --all-tables-with-prefix --dry-run
    You should see: The report now includes any extra plugin tables that contain the old address.
  5. 5

    Run the replacement

    Where: The same SSH session

    Run the same command without --dry-run, keeping any table flag you chose. To produce an SQL file instead of changing the live database (useful when moving to a new server), use --export.

    wp search-replace 'https://old.contoso.com' 'https://contoso.com' --skip-columns=guid --all-tables-with-prefix
    wp search-replace 'https://old.contoso.com' 'https://contoso.com' --skip-columns=guid --export=contoso-new.sql
    You should see: The same table as the dry run, followed by a Success line with the number of replacements made.
  6. 6

    Catch other forms of the old address

    Where: The same SSH session

    Content may also contain the address without the scheme or with http://. Dry-run each variant you find and replace if needed. Keep each pair consistent: no trailing slash on either side.

    wp search-replace 'http://old.contoso.com' 'https://contoso.com' --skip-columns=guid --dry-run
    wp search-replace '//old.contoso.com' '//contoso.com' --skip-columns=guid --dry-run
    You should see: Dry runs for the remaining variants report zero, or you replace the ones that are not zero.
  7. 7

    Confirm home and siteurl and flush caches

    Where: The same SSH session, then a browser

    WordPress says both settings should include https:// and must not end in a slash. Check them, then clear any caching plugin or host cache and load the site.

    wp option get home
    wp option get siteurl
    wp cache flush
    You should see: Both options print https://contoso.com, and pages load with links pointing to the new address.
From experience

Expert tips

Always run --dry-run and read the counts

--dry-run runs the whole operation and prints the per-table report without saving. Check the numbers make sense: thousands in wp_posts and wp_postmeta is normal, a match in a table you did not expect is a reason to stop and look.

Never edit serialized data by hand

WordPress warns that a plain search and replace can break serialized data, because some values store the string length. wp search-replace handles PHP serialized data correctly; sed or a text editor on the SQL file does not. If some plugin values are not replaced, try --precise, which forces PHP processing for all columns.

Use --export to leave the old site untouched

wp search-replace 'https://old.contoso.com' 'https://contoso.com' --skip-columns=guid --export=migrated.sql writes the transformed data to an SQL file instead of changing the database. Import that file on the new server and the old site keeps working as your rollback.

Include custom tables, skip GUIDs

Plugins often create tables that are not registered with WordPress. Use --all-tables-with-prefix to include tables with your prefix, and always --skip-columns=guid, because WordPress says never to change the GUID column.

Keep it fast

--log and --precise slow the run significantly, and --regex takes about 15 to 20 times longer. Use plain string replacements and run several simple passes (for http://, https:// and // forms) rather than one regular expression.

Check it worked

How to confirm it worked

  • A final dry run for the old address returns zero replacements: wp search-replace 'https://old.contoso.com' 'https://contoso.com' --skip-columns=guid --dry-run.

  • Open several pages and the Media Library in a private browser window and check links and images load from the new address.

  • Log in to wp-admin at the new address and check Settings > General shows the new WordPress Address and Site Address.

Undo

How to reverse it

Rollback:

Restore the backup taken in step 1: wp db import before-search-replace.sql, then clear any caches. This replaces the whole database, so any orders, comments or posts created after the backup are lost.

Troubleshooting

Errors you might see

Widgets, theme settings or page builder layouts lost after a URL change

Cause: A find-and-replace was run on the SQL file or with plain SQL, breaking PHP serialized data.

Fix: Restore the backup and redo the change with wp search-replace, which handles serialized data.

GUID column was changed by a search and replace (symptom)

Cause: The command was run without --skip-columns=guid.

Fix: Restore the backup and rerun with --skip-columns=guid. WordPress says never to change the GUID column.

Some URLs in a plugin's data were not replaced

Cause: The plugin's tables are not registered with WordPress, so the default run skipped them. Tables without a primary key are also skipped.

Fix: Rerun with --all-tables-with-prefix or --all-tables (dry run first).

Error establishing a database connection

Cause: wp-config.php database settings are wrong for this server.

Fix: Fix DB_NAME, DB_USER, DB_PASSWORD and DB_HOST in wp-config.php, then rerun.

FAQ

Questions

Can I just edit the SQL file in a text editor?

No. WordPress warns that a search and replace on the whole database can break serialized data. Use wp search-replace, which handles it.

Should I include a trailing slash?

No. Use the address with https:// and no trailing slash on both sides, matching how WordPress stores home and siteurl.

Do I change the GUID column when moving domains?

No. WordPress says never to change the contents of the GUID column. Always add --skip-columns=guid.

How do I do this on multisite?

Use --network to cover all sites, or --url to target one site.

Sources

Official sources

Vendors change menus and requirements. Confirm on the source before you rely on a detail. Last checked 4 Nov 2026.