WordPressMaintenanceUpgradePluginsThemesWordPress 6.xWordPress 7.xIntermediateCurrent

How to Update WordPress Core, Plugins and Themes Safely with WP-CLI

A step-by-step WP-CLI update workflow: backups, maintenance mode, staged plugin, theme and core updates, database upgrades and checksum verification.

Why script your updates at all

The dashboard updater works fine for a single low-stakes site. Once you maintain several installations, or a production site where a broken plugin update costs money by the hour, clicking through wp-admin stops being a reasonable process. You lose the log of what happened, you cannot review what would be updated before it happens, and you cannot run the same sequence on staging and production with confidence that they match.

WP-CLI, WordPress’s official command-line interface, turns the update routine into a repeatable script: check what is pending, snapshot the current state, put the site into maintenance mode, update extensions and core in a deliberate order, run the database upgrade, verify the result, and switch the site back on. Every command reference used in this guide is documented on the official command pages at developer.wordpress.org/cli/commands/.

The order below is not the only defensible one, but it is the one we use: extensions first, core last. The reasoning is simple — a plugin or theme updated while core is still old is usually still compatible with the new core, while a plugin that is already abandoned will reveal itself before you have committed to the new core version.

Step 0: Snapshot before anything else

No update command in this guide is dangerous on a healthy site, but “healthy” is an assumption, not a fact. Before running anything, take a full backup of files and database — through your hosting provider’s snapshot tool, your backup plugin, or both. If you use WP-CLI’s database tooling, wp db export produces a plain SQL dump you can restore on any MySQL-compatible host.

Confirm the basics while you are here:

wp core version
wp core check-update
wp plugin list --update=available
wp theme list --update=available

This is your inventory: what version you run, what is pending, and how big the update window needs to be. If the pending list includes a plugin whose maintainer has not shipped a release in years, decide now whether it gets updated, replaced, or dropped — not after it takes the site down.

On a staging copy, rehearse the full sequence before touching production. An update that breaks staging will break production the same way, and finding that out early is the entire point of staging.

Step 1: Maintenance mode on

WP-CLI ships a maintenance mode that serves visitors the standard maintenance notice while you work. The command pages document four subcommands:

wp maintenance-mode activate
wp maintenance-mode status
wp maintenance-mode is-active
wp maintenance-mode deactivate

is-active is the scripting-friendly variant: it reports state through its exit code, so a deployment script can verify the mode actually engaged instead of assuming it.

Maintenance mode is a courtesy to visitors and a safety measure for you — it prevents half-updated PHP from being served to real traffic and keeps orders, form submissions and crawler activity out of your update window. A few minutes of downtime notice is cheaper than a visitor capturing a fatal error.

Step 2: Update plugins, one batch at a time

The plugin update command accepts individual slugs or a bulk run:

wp plugin update --all
wp plugin update --all --exclude=akismet
wp plugin update some-plugin --version=2.4.1

The --exclude flag matters more than it looks. Every long-lived WordPress site accumulates one or two plugins that must not be updated casually — an old custom integration, a plugin pinned for a client workflow, something whose new major version changes behavior. Pin those by name in the exclude list and let the rest move.

On a site you have never maintained this way, resist the urge to run --all immediately. Update in small batches, check the front end and the critical admin screens after each batch, and you will know exactly which update broke something if something breaks. The site already told you what changed; wp plugin list shows versions, so keep its output before and after.

Step 3: Update themes

The theme command mirrors the plugin command, with the same flags documented on its reference page:

wp theme update --all --dry-run
wp theme update --all

--dry-run previews what would be updated — useful when you want the change log before committing. Note that if you run a custom child theme or a fully custom theme, there is nothing to update from the repository, and this step is about third-party parent themes or commercial themes distributed through the updater.

If your active theme has available updates, this is the moment to re-test the templates that matter most: the homepage, a standard post or page, any custom post type archive, and the checkout or contact flow.

Step 4: Update WordPress core

With extensions already on their newest compatible versions, update core itself:

wp core update

By default this moves the installation to the latest release. The command also accepts targeted forms — wp core update --minor stays within the current minor branch, and --version=<version> pins a specific release, which is what you use when you deliberately upgrade one step at a time on a site that has fallen several major versions behind.

After the files are replaced, run the database procedure:

wp core update-db

This performs the same database upgrade you would trigger by visiting the dashboard update screen after a core update. On multisite, add --network to run it across every site. Skipping this step is a classic source of strange behavior after a core update: new files, old schema.

Step 5: Verify what you actually installed

The update reported success, but verify anyway:

wp core verify-checksums

This compares your installed core files against the checksums published by WordPress.org and warns about any file that does not match. It is a quick, cheap integrity check that catches two things: a corrupted download, and core files that were modified on disk by something other than the updater. The command documentation notes it runs without loading WordPress itself, which is exactly what you want from an integrity check. If it reports mismatches you cannot explain, stop and investigate before proceeding — modified core files are a security question, not a cosmetic one.

Step 6: Test, then switch the site back on

Before deactivating maintenance mode, walk through the site as a visitor and as an editor: homepage, key templates, forms, and the admin screens your team uses daily. Watch the server error log during the first minutes of real traffic after the update — that log is where problems surface that a quick browse will miss.

Then:

wp maintenance-mode deactivate

If something did break, the response is not improvisation. Restore the snapshot, and re-run the sequence with the failing update held back via --exclude or a pinned --version. That is the whole reason the snapshot exists.

When the updater gets stuck

A specific failure mode is worth knowing because it looks scarier than it is: WordPress reports “Another update is currently in progress” and refuses to update. This happens when a previous update run was interrupted and left its lock behind. The wp core update documentation gives the fix directly:

wp option delete core_updater.lock

Delete the stale lock, re-run the update, and it proceeds. Do not confuse this with a real concurrent update — if a teammate may genuinely be mid-update, check with them first.

Maintenance is a routine, not an event

Updates done this way take minutes once the sequence is scripted, which is precisely why they get done. Sites fall behind not because updates are hard but because each dashboard session feels like a small gamble. A repeatable WP-CLI routine — snapshot, maintenance mode, staged extensions, core, database, checksums, test — removes the gamble, and rehearsing it on staging removes the rest.

When an update window repeatedly surfaces problems instead — plugins that break on every new core release, a theme stack nobody dares touch, error patterns like the 500 internal server errors we cover separately — that is usually a sign the code base needs attention rather than another careful update. Our WordPress development service handles exactly this kind of work, from plugin compatibility repairs to full rebuilds, and the WordPress platform page describes what we maintain on that stack in general.

The same staged discipline applies to larger version jumps on other systems, too — our TYPO3 v12 to v13 upgrade guide follows the same pattern of inventory, rehearsal and verification, and the trade-offs between maintaining a platform versus migrating are covered in our article on choosing a CMS for your business.

Related guides

Continue with the surrounding work.

More WordPress guides
Related insights

Broader context from the YCTheme blog.