Managing WordPress with WP-CLI on a VPS

The WordPress admin dashboard works fine — especially on a properly tuned VPS. But "fine" has overhead. Every plugin install, every core update, every search-replace fires up a PHP-FPM worker, routes through Nginx, and renders an admin page you have to click through. Even when it's fast, it's heavier than it needs to be.

WP-CLI runs directly on the server, without PHP-FPM, without Nginx, without a browser. A plugin update that takes a few seconds and a page reload in the admin finishes in under a second at the terminal — and uses a fraction of the memory. A search-replace across 50,000 post rows runs at the database level with no PHP timeout risk. And if you manage more than one WordPress site, the real payoff is scripting: update every plugin across every site with a single command. Schedule database maintenance across all of them from one cron file. Deploy a new site from a one-liner.

This isn't a comprehensive reference (the WP-CLI Handbook already exists). It's the subset of commands that actually matter when you're managing WordPress on your own server.


Step 1: Install WP-CLI

WP-CLI is a single PHP archive — no package dependencies, no extensions to enable. Download it, make it executable, and verify:

cd /tmp
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
sudo chmod +x /usr/local/bin/wp

# Verify
wp --info

On Debian/Ubuntu, it's also available via apt install wp-cli, but the package manager version often lags months behind the upstream release. The direct download is the recommended approach and takes 30 seconds.


Step 2: Install WordPress from the command line

Instead of downloading a zip, unpacking it, and running the five-minute installer in a browser, do it in four commands:

# Download core
wp core download --path=/var/www/mysite.com/public_html --locale=en_US

# Create wp-config.php
wp config create \
    --dbname=mysite_db \
    --dbuser=mysite_user \
    --dbpass=generate-a-strong-password-here \
    --dbhost=localhost \
    --path=/var/www/mysite.com/public_html

# Set salts (auto-generated from the WordPress API)
wp config shuffle-salts --path=/var/www/mysite.com/public_html

# Install
wp core install \
    --url=https://mysite.com \
    --title="My Site" \
    --admin_user=yourname \
    --admin_email=you@example.com \
    --admin_password=$(wp pwgen 24 1) \
    --path=/var/www/mysite.com/public_html

The last command prints your generated admin password — copy it somewhere safe. wp pwgen creates a 24-character random string that beats anything you'd type manually.

A few extra wp config flags worth knowing:

# Disable the built-in cron (use system cron instead)
wp config set DISABLE_WP_CRON true --raw --path=/var/www/mysite.com/public_html

# Set memory limits
wp config set WP_MEMORY_LIMIT 256M --path=/var/www/mysite.com/public_html
wp config set WP_MAX_MEMORY_LIMIT 256M --path=/var/www/mysite.com/public_html

# Disable the plugin/theme file editor (defense in depth)
wp config set DISALLOW_FILE_EDIT true --raw --path=/var/www/mysite.com/public_html

# Force SSL for the admin area
wp config set FORCE_SSL_ADMIN true --raw --path=/var/www/mysite.com/public_html

Once WordPress is installed, you'll still need to configure your webserver to serve it — virtual host, document root, PHP handler, and any security or caching rules specific to your stack. If you're on Nginx, the WordPress on Nginx installation guide covers the full production configuration.

The whole process — from blank directory to working WordPress install — takes under a minute.


Step 3: Plugin and theme management

The admin dashboard makes you search, click Install, wait, click Activate, wait, and repeat for every plugin. WP-CLI collapses that into single commands:

# Search for a plugin
wp plugin search "webp" --path=/var/www/mysite.com/public_html

# Install and activate in one step
wp plugin install modern-image-formats --activate --path=/var/www/mysite.com/public_html

# Install multiple plugins at once
wp plugin install wordfence yoast-seo wp-super-cache --activate --path=/var/www/mysite.com/public_html

# Deactivate without deleting (troubleshooting)
wp plugin deactivate wp-optimize --path=/var/www/mysite.com/public_html

# Delete a plugin entirely
wp plugin delete wp-optimize --path=/var/www/mysite.com/public_html

# Update everything
wp plugin update --all --path=/var/www/mysite.com/public_html
wp theme update --all --path=/var/www/mysite.com/public_html

Not every plugin earns its keep. Some optimization and caching plugins run filesystem scans on every page load — and on a VPS where nginx and Cloudflare already handle those jobs, the plugin adds overhead without adding value. The article on when WordPress plugins hurt more than they help covers how to audit what you install and what the server layer already handles for free.

Themes work identically — replace plugin with theme in any of the above:

wp theme install generatepress --activate --path=/var/www/mysite.com/public_html
wp theme list --path=/var/www/mysite.com/public_html

wp theme list and wp plugin list print a table of everything installed with version numbers and status — faster than scrolling through the admin screens, especially on a site with 20+ plugins.


Step 4: Database maintenance

WordPress accumulates post revisions, trashed posts, spam comments, expired transients, and orphaned metadata. Cleaning these on a schedule keeps the database lean:

# Full optimization — rebuilds tables and reclaims disk space
wp db optimize --path=/var/www/mysite.com/public_html

# Repair (for when things go wrong)
wp db repair --path=/var/www/mysite.com/public_html

# Check for issues without making changes
wp db check --path=/var/www/mysite.com/public_html

Schedule it weekly via cron:

# /etc/cron.d/wordpress-db — weekly at 4 AM Sunday
0 4 * * 0 www-data wp db optimize --path=/var/www/mysite.com/public_html

The --path flag is mandatory when running wp-cli from cron — there's no current working directory context, so wp-cli can't auto-detect the WordPress install location.

If you're coming from shared hosting, you may be used to a plugin handling database cleanup. On a VPS, a weekly wp-cli cron job replaces that entirely — no plugin overhead, no init hook firing on every page load just to check if a cleanup is due.