
How to Use WP-CLI to Manage WordPress from the Command Line?
Updating twenty plugins on one site takes a few clicks. Updating twenty plugins on fifteen client sites, exporting each database first, and confirming nothing broke takes an afternoon in the dashboard. The same job takes a few minutes with WP-CLI, the official command-line interface for WordPress. It also handles the tasks the dashboard cannot do well: replacing a domain across a serialized database, resetting a locked-out admin password, deactivating a plugin that crashes the site, or regenerating thousands of thumbnails without a browser timeout.
This article covers installing WP-CLI, how its commands and global options work, and the commands you will use most for core, plugins, themes, users, content, options, the database, search and replace, cache, cron, and media. It then shows how to manage remote sites with aliases, how to script routine maintenance, and how to stay safe when every command runs against a live database.
What Is WP-CLI?
WP-CLI is a command-line tool, invoked as wp, that loads WordPress and runs commands against it. Because it uses WordPress's own PHP functions, a command such as wp plugin update does exactly what the dashboard does, including running update routines and clearing caches, but without a browser, without HTTP timeouts, and in a form you can script.
| Task | Dashboard | WP-CLI |
|---|---|---|
| Update all plugins | Several clicks per site | wp plugin update --all |
| Change the site URL after a migration | SQL or a plugin, risky with serialized data | wp search-replace with a dry run |
| Reset a forgotten admin password | Email reset, if email works | wp user update with a new password |
| Deactivate a plugin that breaks the site | Impossible if the admin is down | wp plugin deactivate with plugins skipped |
| Regenerate all image sizes | Plugin, often times out | wp media regenerate |
| Back up the database | Plugin or hosting panel | wp db export |
Installing WP-CLI
Many managed WordPress hosts include WP-CLI already. Connect over SSH and run wp --info. If it prints version details, skip ahead.
On Linux and macOS
WP-CLI is distributed as a single PHAR file. Download it, check that it runs, make it executable, and move it onto your path:
# Terminal
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info
On macOS, Homebrew also works: brew install wp-cli. To update a PHAR install later, run wp cli update.
On Windows
WP-CLI runs best inside WSL (Windows Subsystem for Linux), where you follow the Linux steps above. It can also run natively with a PHP install and a small batch file wrapper, but WSL avoids most path and shell issues.
Enabling tab completion
WP-CLI provides a completion script for Bash and Zsh. Download wp-completion.bash from the WP-CLI repository and source it in your shell profile, and you can press Tab to complete commands and subcommands.
How WP-CLI Commands Work
Every command follows the same pattern:
# Terminal
wp <command> <subcommand> [arguments] [--flags]
For example, wp plugin install query-monitor --activate runs the install subcommand of the plugin command with one argument and one flag. Discover anything with built-in help:
# Terminal
wp help
wp help plugin
wp help plugin install
WP-CLI must run where it can find WordPress. Either cd into the WordPress root (the folder containing wp-config.php), or point to it with --path.
Global parameters worth knowing
These flags work with any command:
| Flag | What it does |
|---|---|
--path=<path> | The WordPress install to use |
--url=<url> | Which site to target, required for specific sites in multisite |
--user=<id|login> | Runs the command as a specific user, for capability-aware commands |
--skip-plugins | Loads WordPress without plugins, or without listed ones |
--skip-themes | Loads WordPress without the active theme |
--ssh=<host> | Runs the command on a remote server over SSH |
--quiet | Suppresses informational messages |
--debug | Prints debugging output, useful when a command fails silently |
Output formats
Most list commands accept --format and --fields, which turn WP-CLI into a reporting tool:
# Terminal
wp plugin list --fields=name,status,version,update --format=table
wp plugin list --status=active --format=json
wp post list --post_type=page --format=csv > pages.csv
wp user list --role=administrator --format=count
wp post list --post_status=draft --format=ids
The ids format outputs a space-separated list, which is perfect for piping one command into another.
Run as the web server user, not root
WP-CLI refuses to run as root unless you add --allow-root, because files created by root can end up unwritable by the web server. On servers where PHP runs as www-data, run commands as that user instead:
# Terminal
sudo -u www-data wp plugin list
Managing WordPress Core
# Terminal
wp core version
wp core check-update
wp core update
wp core update-db
wp core verify-checksums
wp core verify-checksums compares every core file against the official checksums from WordPress.org and reports anything modified or added. It is one of the fastest ways to spot a hacked install. For a fresh installation from scratch, WP-CLI handles every step:
# Terminal
wp core download --locale=en_US
wp config create --dbname=example --dbuser=example --prompt=dbpass
wp db create
wp core install --url=https://example.com --title="Example Site" --admin_user=siteadmin --admin_email=admin@example.com --prompt=admin_password
The --prompt option asks for the listed values interactively, so passwords do not end up in your shell history. A dashboard-based walkthrough is in how to install WordPress.
Managing Plugins and Themes
The plugin and theme commands mirror each other:
# Terminal
wp plugin list
wp plugin install query-monitor --activate
wp plugin install https://example.com/downloads/premium-plugin.zip --activate
wp plugin update --all --dry-run
wp plugin update --all
wp plugin update woocommerce --version=11.2.0
wp plugin deactivate hello
wp plugin delete hello akismet
wp plugin verify-checksums --all
wp theme list
wp theme install twentytwentyfive --activate
wp theme update --all
wp theme delete twentytwentythree
Useful details:
--dry-runonupdatelists what would change without updating anything.--versioninstalls or rolls back to a specific version from WordPress.org, which is handy when an update breaks something.wp plugin verify-checksumschecks plugin files from the WordPress.org directory against their published checksums.
For a safe update routine with backups and testing, combine these commands with the process in how to update WordPress plugins and themes.
Rescuing a site broken by a plugin
When a plugin causes a fatal error, the dashboard is unreachable, but WP-CLI can still load WordPress without plugins:
# Terminal
wp plugin list --status=active --skip-plugins --skip-themes
wp plugin deactivate broken-plugin --skip-plugins --skip-themes
If you do not know which plugin is responsible, deactivate them all, then reactivate one at a time:
# Terminal
wp plugin list --status=active --field=name --skip-plugins --skip-themes > active-plugins.txt
wp plugin deactivate --all --skip-plugins --skip-themes
wp plugin activate $(head -n 1 active-plugins.txt)
Managing Users
# Terminal
wp user list --fields=ID,user_login,user_email,roles
wp user create jane jane@example.com --role=editor --send-email
wp user set-role jane author
wp user update siteadmin --user_pass="$(openssl rand -base64 24)" --skip-email
wp user reset-password jane
wp user delete olduser --reassign=1
wp user updatewith--user_passsets a password directly, which is the standard fix for a locked-out administrator.wp user reset-passwordsends a reset email, so the user picks their own password.--reassignondeletetransfers the deleted user's content to another user ID instead of deleting it.
Managing Posts, Pages, and Content
# Terminal
wp post list --post_type=page --post_status=publish --fields=ID,post_title,post_name
wp post create --post_type=page --post_title="About Us" --post_status=draft
wp post update 42 --post_status=publish
wp post meta list 42
wp post delete $(wp post list --post_status=trash --format=ids) --force
wp post generate --count=20 --post_type=post
wp comment delete $(wp comment list --status=spam --format=ids) --force
wp post generate creates placeholder posts, which is useful for testing themes and pagination on a local site. Never run it on production.
Managing Options and Configuration
Options are the site settings stored in the wp_options table:
# Terminal
wp option get blogname
wp option update blogname "Web Solution Master"
wp option get siteurl
wp option update default_comment_status closed
wp rewrite structure '/%postname%/'
wp rewrite flush
The config command edits wp-config.php safely, without opening the file:
# Terminal
wp config get DB_NAME
wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set DISALLOW_FILE_EDIT true --raw
wp config shuffle-salts
--raw writes the value as PHP code, so true becomes a boolean rather than the string "true". wp config shuffle-salts replaces the authentication keys and salts, which logs every user out. Do that after a security incident.
Working with the Database
# Terminal
wp db size --tables --human-readable
wp db export backup-$(date +%F).sql
wp db import backup-2026-10-09.sql
wp db check
wp db optimize
wp db query "SELECT option_name FROM wp_options WHERE autoload IN ('yes','on') ORDER BY LENGTH(option_value) DESC LIMIT 10;"
wp db search "old-domain.com"
wp db export is the quickest backup before any risky change. It uses the credentials in wp-config.php, so you never type a database password. For a complete files-and-database strategy, see how to create a backup for a WordPress website.
Search and replace, the right way
Moving a site to a new domain or to HTTPS means updating URLs throughout the database. A plain SQL REPLACE corrupts serialized data, the format WordPress uses for many options and widget settings, because serialized strings store their length. wp search-replace unserializes, replaces, and reserializes correctly:
# Terminal
wp db export before-search-replace.sql
wp search-replace 'https://staging.example.com' 'https://example.com' --skip-columns=guid --dry-run
wp search-replace 'https://staging.example.com' 'https://example.com' --skip-columns=guid --report-changed-only
wp cache flush
Always run with --dry-run first to see how many replacements each table will receive. --skip-columns=guid leaves post GUIDs unchanged, which is the WordPress recommendation. On multisite, add --network to cover every site's tables, or --url to target one site. This command is the core of most migrations, described end to end in how to migrate a WordPress website to a new hosting provider.
Cache, Transients, Cron, and Maintenance Mode
# Terminal
wp cache flush
wp transient delete --expired
wp transient delete --all
wp cron event list
wp cron event run --due-now
wp cron test
wp maintenance-mode activate
wp maintenance-mode deactivate
wp maintenance-mode status
wp cache flushclears the object cache. It does not clear page caches from caching plugins, which usually provide their own WP-CLI commands.wp transient delete --expiredremoves stale transients that some plugins leave behind.wp cron event run --due-nowruns overdue scheduled tasks immediately, which is how many servers replace the visitor-triggered WP-Cron with a real cron job, as described in how to replace WP-Cron with a real server cron job.
Working with Media
# Terminal
wp media regenerate --only-missing --yes
wp media import ~/photos/*.jpg --post_id=42 --featured_image
wp media image-size
After changing image sizes in a theme, wp media regenerate rebuilds thumbnails for the whole library without the browser timeouts that dashboard plugins hit. --only-missing skips sizes that already exist, which is much faster on large sites.
Scaffolding Plugins and Themes
WP-CLI can generate starter files that follow WordPress coding standards:
# Terminal
wp scaffold plugin mysite-functions --plugin_name="My Site Functions" --activate
wp scaffold child-theme my-child-theme --parent_theme=twentytwentyfive --activate
wp scaffold post-type recipe --plugin=mysite-functions
wp scaffold taxonomy cuisine --post_types=recipe --plugin=mysite-functions
The generated code is a starting point. Review it, especially the post type and taxonomy arguments, before using it in production. The taxonomy arguments are explained in how to register custom taxonomies in WordPress.
Managing Remote Sites with Aliases
WP-CLI can run commands on other servers over SSH, as long as WP-CLI is installed on the remote server too. Define aliases in a wp-cli.yml file in your project, or in ~/.wp-cli/config.yml for global aliases:
# wp-cli.yml
@staging:
ssh: deploy@staging.example.com/var/www/example/htdocs
@production:
ssh: deploy@example.com/var/www/example/htdocs
@all:
- @staging
- @production
Now prefix any command with an alias:
# Terminal
wp @staging plugin list
wp @production core version
wp @all plugin update --all --dry-run
wp @production db export - > production-$(date +%F).sql
The last command streams the production database export to your local machine. Passing - as the file name sends the SQL to standard output. Aliases rely on your normal SSH configuration, so keys and host settings in ~/.ssh/config apply.
Scripting Routine Maintenance
Because WP-CLI is a command-line tool, routine work becomes a shell script. This example backs up the database, runs updates, and verifies checksums on one site:
#!/usr/bin/env bash
# ~/bin/wp-maintain.sh
set -euo pipefail
SITE_PATH="/var/www/example/htdocs"
BACKUP_DIR="$HOME/backups"
STAMP=$(date +%F-%H%M)
mkdir -p "$BACKUP_DIR"
cd "$SITE_PATH"
echo "Backing up database..."
wp db export "$BACKUP_DIR/example-$STAMP.sql" --quiet
echo "Updating core, plugins, and themes..."
wp core update
wp core update-db
wp plugin update --all
wp theme update --all
wp language core update
wp language plugin update --all
echo "Verifying core and plugin files..."
wp core verify-checksums
wp plugin verify-checksums --all || echo "Some plugins could not be verified (premium or custom plugins are expected here)."
echo "Clearing caches..."
wp cache flush
wp transient delete --expired
echo "Done."
Run it manually, or schedule it with cron during low-traffic hours. For anything business-critical, run updates on staging first and keep a human in the loop for production. Automatic updates without testing are how sites break overnight.
Common Problems and Fixes
- "Error: This does not seem to be a WordPress installation." You are not in the WordPress root.
cdinto the folder containingwp-config.php, or pass--path. - "Error establishing a database connection" only in WP-CLI. The command-line PHP cannot reach the database, often because
DB_HOSTislocalhostand the CLI uses a different socket than the web server. Try127.0.0.1inDB_HOST, or checkphp --inifor the CLI configuration. - "YIKES! It looks like you're running this as root." Run the command as the web server user with
sudo -u www-data wp ..., or add--allow-rootonly when you understand the file ownership consequences. - A command crashes because of a plugin or theme. Add
--skip-plugins --skip-themesto load WordPress without them. - Memory exhausted on large operations. Raise the CLI memory limit for one command with
php -d memory_limit=512M $(which wp) media regenerate. - Multisite commands affect the wrong site. Pass
--url=https://site.example.comto target a specific site.
WP-CLI FAQ
To use it on a live server, yes. WP-CLI runs on the machine where WordPress is installed, so you need SSH or a hosting terminal. Many managed hosts provide both. On a local development site you run it directly in your terminal.
It is as safe as the dashboard, because it uses the same WordPress functions, but there is no confirmation screen for most commands. Export the database before risky changes, use dry-run options where available, and test on staging first.
WordPress stores many settings as serialized PHP data that includes string lengths. A plain SQL replace changes the text without updating those lengths, which breaks the data. WP-CLI unserializes values, replaces them, and serializes them again correctly.
Yes. Define aliases for each site in a wp-cli.yml file, including a group alias that lists several sites, and run commands against the group. Each remote server needs WP-CLI installed and SSH access configured.
Yes. Most commands accept a url parameter to target a specific site in the network, and commands such as search-replace accept a network flag to cover every site. The site command manages the network itself.
If you installed the PHAR file, run wp cli update. If you installed it with a package manager such as Homebrew, update it through that package manager instead.
Conclusion
WP-CLI turns WordPress administration from a series of clicks into a set of fast, repeatable commands. Install it once, learn the pattern of command, subcommand, arguments, and flags, and lean on wp help for everything else. The commands for plugins, themes, users, options, and the database cover most daily work, while search-replace, verify-checksums, and --skip-plugins solve problems the dashboard simply cannot.
As your comfort grows, add aliases to manage staging and production from one terminal, and wrap routine maintenance in scripts. Keep the safety habits that matter: export the database first, use dry runs, run as the web server user, and test on staging before production.
Here are some useful references for going deeper on WP-CLI:
- WP-CLI: Installing WP-CLI — official installation steps for every platform.
- WP-CLI Commands: Command reference — every built-in command, subcommand, and option.
- WP-CLI Handbook: Config — global parameters, wp-cli.yml, and aliases.
- WP-CLI Commands: wp search-replace — options for safe database-wide replacements.
- WP-CLI Handbook: Running commands remotely — SSH and alias usage in detail.


