If you manage WordPress sites, you’ll eventually need to find and replace strings in your database. Maybe you’re migrating domains, switching from HTTP to HTTPS, or pushing a staging site to production. The wp search-replace command handles all of this, and it does it correctly, even with serialized data that would break if you used raw SQL queries.
This guide covers everything from basic syntax to advanced regex patterns, with real commands you can copy and adapt for your own projects. Every example here comes from actual migration and maintenance scenarios.
What WP-CLI Search-Replace Actually Does
The wp search-replace command searches through your WordPress database and replaces one string with another. What makes it essential is its ability to handle PHP serialized data, something a direct SQL UPDATE statement cannot do without corrupting your database.
WordPress stores serialized arrays and objects throughout its database, particularly in the wp_options table, widget settings, and post meta. These serialized strings include byte counts. Change a URL length without updating the byte count and the data becomes unreadable. WP-CLI handles this automatically by unserializing the data, making the replacement, and re-serializing it with correct byte counts. If you’re not familiar with WordPress database structure, our guide on the different types of WordPress default tables explains what each table stores and why it matters.
According to the official WP-CLI documentation, the command searches through all rows in a selection of tables and replaces appearances of the first string with the second string. It will correctly handle serialized values and will not change primary key values.
Basic Syntax and Core Options
The fundamental syntax is straightforward:
The first argument is the string you want to find. The second is the replacement. Optionally, you can specify which tables to search. Without specifying tables, WP-CLI searches all tables registered to the current WordPress installation (those matching the configured table prefix).
Here are the most important flags you should know:
--dry-run, Shows what would change without making any modifications. Always run this first.--precise, Forces the use of PHP serialization handling for all columns. Slower but more thorough.--all-tables, Searches all database tables, not just those with your WordPress prefix.--all-tables-with-prefix, Searches all tables that share the WordPress table prefix.--verbose, Prints detailed information about each replacement.--format=count, Outputs just the replacement count for scripting.
The Golden Rule: Always Dry-Run First
Before running any search-replace operation on a production database, you must use --dry-run. This is non-negotiable. The dry-run flag simulates the operation and tells you exactly how many replacements would occur in each table, without modifying a single row.
Notice the “Type” column. “PHP” means the data is serialized and WP-CLI will handle it properly. “SQL” means a direct string replacement. Review the numbers carefully, if something looks off (like zero replacements when you expected many), your search string might be wrong.
Real Example 1: Domain Migration
Domain migration is the most common use case. You’re moving a site from one domain to another and every URL in the database needs to update. Here’s the proper sequence:
Running the replacement in two passes, first with the full protocol, then with protocol-relative URLs, catches references stored in different formats. Some plugins store URLs with // prefixes, and email templates sometimes reference the bare domain.
John Blackbourn, a WordPress Core committer and developer of the Query Monitor plugin, has noted that “running search-replace without a backup is like editing production code without version control, you’re one mistake away from a very bad day.” Always export your database before any bulk operation.
Real Example 2: HTTP to HTTPS Migration
After installing an SSL certificate, you need to update all internal URLs from http:// to https://. This is one of the cleanest use cases for search-replace:
After running this, verify your site loads correctly over HTTPS. Check for mixed content warnings in the browser console, if any remain, run a more aggressive search.
The --all-tables flag extends the search beyond WordPress core tables to include tables created by plugins that might not use the standard table prefix.
Real Example 3: Staging to Production
Pushing a staging site to production requires replacing the staging URL with the live URL. This scenario often involves multiple replacements because staging environments sometimes have different directory structures. If you need help setting up a local staging environment first, check out our tutorial on how to install WordPress on localhost.
The --path flag tells WP-CLI where to find the WordPress installation. This is critical when you’re managing multiple environments from a single server or when running commands remotely.
Real Example 4: Fixing Broken Image URLs
After migrating a site or changing your uploads directory structure, image URLs can break across hundreds of posts. Instead of manually editing each post, use search-replace to fix them all at once:
Notice that these commands target specific tables (wp_posts and wp_postmeta). When you know exactly where the broken references live, targeting specific tables speeds up the operation and reduces risk.
Handling Serialized Data Correctly
Serialized data is the primary reason you should use WP-CLI instead of raw SQL for search-replace operations. Here’s what serialized data looks like in the database:
See the s:45? That’s a byte count. If you change oldsite.com to newsite.com using a raw SQL query, the URL length changes but the byte count stays at 45. WordPress then can’t unserialize the data, and the value is lost.
WP-CLI unserializes the data first, makes the replacement, then re-serializes it with the correct byte count. This is transparent to you as the user, WP-CLI handles it automatically. But if you ever see “PHP” in the Type column of your dry-run output, you know serialized data is being handled correctly.
Targeting Specific Tables
You don’t always want to search-replace across the entire database. Targeting specific tables is faster, safer, and gives you more control:
You can list multiple table names after the replacement string. This is particularly useful when you know a change only affects post content (not options or user meta), or when you want to update plugin-specific tables without touching the rest of the database.
Advanced: Regex Mode
For pattern-based replacements, WP-CLI supports PCRE regular expressions with the --regex flag. This opens up powerful possibilities:
Regex mode uses PCRE (Perl Compatible Regular Expressions) syntax. Capture groups work with $1, $2, etc. in the replacement string. Be extra careful with regex replacements, always dry-run first and review the replacement count carefully. A wrong pattern can corrupt content across your entire database.
One important caveat: regex mode is significantly slower than standard mode because every value must be processed through PHP’s regex engine. On large databases (100K+ rows), consider targeting specific tables to keep execution time reasonable.
Advanced: Skip Columns and Tables
Sometimes you need to exclude certain columns from the search-replace operation. The --skip-columns flag handles this:
The guid column in wp_posts deserves special attention. GUIDs are meant to be permanent identifiers. The WordPress Codex explicitly states that GUIDs should not be changed, as they’re used by RSS feeds to track which posts have been read. However, during a full domain migration, leaving old URLs in the GUID column is generally harmless, RSS readers might re-show some posts, but that’s typically the lesser concern.
The general recommendation from WordPress VIP and experienced developers: skip the GUID column unless you have a specific reason to change it.
Advanced: Export and Import Workflow
For complex migrations or when you want to test replacements without touching the live database, use an export/import workflow:
The --export flag outputs a new SQL file with all replacements applied, without modifying the current database. This is perfect for testing migrations locally before applying them to production, or for creating migration-ready database dumps.
Common Pitfalls and How to Avoid Them
After running thousands of search-replace operations across WordPress sites, these are the mistakes that catch people most often:
Multisite Considerations
On WordPress Multisite installations, search-replace has additional considerations. Each sub-site has its own set of tables, and you need to decide whether to run the replacement network-wide or per-site:
The --network flag iterates through all sub-sites. The --url flag targets a specific sub-site by its URL. For large networks, consider running replacements per-site to monitor progress and catch issues early.
Performance Tips for Large Databases
On databases with millions of rows, search-replace can take a long time. Here are proven strategies to speed things up:
- Target specific tables, Don’t search the entire database if you know the change only affects
wp_posts. - Use
--skip-columns, Skip columns that can’t possibly contain the target string (like integer columns or datetime columns). - Increase PHP memory, For very large tables, you might need:
wp search-replace --memory_limit=512M - Run during low-traffic hours, Search-replace creates row locks. On a live site, run during your lowest-traffic window.
- Consider
--report-changed-only, Reduces output noise by only showing tables where changes were made.
Scripting and Automation
WP-CLI search-replace integrates well into deployment scripts and CI/CD pipelines. Here’s a practical migration script:
Using set -e at the top ensures the script stops immediately if any command fails, critical for migration scripts where a failed step means subsequent steps will cause problems. When building scripts that interact with your database, understanding SQL tools for WordPress can help you verify data integrity before and after migrations.
WP-CLI Search-Replace Cheat Sheet
Bookmark this table for quick reference. These are the commands and flags you will use most often:
| Command / Flag | What It Does | When to Use |
|---|---|---|
wp search-replace 'old' 'new' | Replace in all WP-prefix tables | Standard domain migration |
--dry-run | Preview without changing data | Always run first |
--precise | PHP serialization for all columns | When serialized data might be missed |
--all-tables | Search every table in the database | Plugin tables with non-standard prefixes |
--all-tables-with-prefix | All tables matching WP prefix | Multisite or shared-database setups |
--skip-columns=guid | Exclude specific columns | Avoid changing post GUIDs |
--skip-tables=wp_users | Exclude specific tables | Protect sensitive tables |
--regex | Enable PCRE regex patterns | Pattern-based replacements |
--export=file.sql | Write changes to SQL file | Test before applying to live DB |
--network | Run across all Multisite sub-sites | Network-wide URL changes |
--url=site.com | Target specific Multisite sub-site | Per-site replacement |
--verbose | Show each replacement | Debugging unexpected results |
--report-changed-only | Only show tables with changes | Cleaner output on large databases |
--format=count | Output replacement count only | Scripting and CI/CD pipelines |
wp db export backup.sql | Export database to SQL file | Before every search-replace |
wp cache flush | Clear WordPress object cache | After every search-replace |
Final Thoughts
The wp search-replace command is one of the most powerful tools in the WordPress developer’s toolkit. It handles the complexity of serialized data, gives you dry-run safety, supports regex for complex patterns, and integrates cleanly into automation scripts.
The workflow for any search-replace operation should always be: backup, dry-run, review, execute, flush caches. Skip any of these steps and you’re taking unnecessary risks with your database.
For the official and most up-to-date documentation, refer to the WP-CLI search-replace command reference. The WP-CLI handbook is also an excellent resource for understanding how the tool works under the hood and exploring related commands like wp db query and wp db optimize.
Database Migration Domain Migration Search Replace WordPress Database WP-CLI
Last modified: February 24, 2026