These eight checks help establish whether a WordPress installation is intact, keeping up with scheduled work and using its server sensibly. I run WP-CLI from the correct site directory under its service account, and distinguish inspection from commands which deliberately change the installation.
1. Prove your core files are genuine
wp core verify-checksums
wp plugin verify-checksums --allThis compares every core file with the official release. Modified files can mean a hack. Extra files usually come from years of in-place upgrades. Either way, you want to know.
2. Run cron on a real schedule
By default WordPress checks for scheduled jobs on page views. Busy sites check too often, quiet sites miss jobs, and cached pages never trigger it at all. Hand it to the server:
// wp-config.php
define( 'DISABLE_WP_CRON', true );# Every five minutes, as the site's user
*/5 * * * * cd /var/www/example && wp cron event run --due-now --quiet3. Check autoloaded options
WordPress loads every autoloaded option on every request. Plugins that store big data there slow every single page:
wp db query "SELECT ROUND(SUM(LENGTH(option_value))/1024) AS autoload_kb
FROM $(wp db prefix)options WHERE autoload IN ('yes','on','auto-on','auto');"
# The ten biggest offenders
wp db query "SELECT option_name, ROUND(LENGTH(option_value)/1024) AS kb
FROM $(wp db prefix)options WHERE autoload IN ('yes','on','auto-on','auto')
ORDER BY LENGTH(option_value) DESC LIMIT 10;"Under a megabyte is comfortable. Several megabytes is worth chasing down.
4. Switch off the built-in file editor
define( 'DISALLOW_FILE_EDIT', true );If an admin login is ever stolen, this stops it being turned straight into code running on your server.
5. Use a persistent object cache
wp cache typeIf that says “Default”, every request rebuilds the same database answers from scratch. A Redis object cache keeps them between requests, and helps most on pages that cannot be cached whole, such as logged-in dashboards and baskets.
6. Clear out expired transients
wp transient delete --expired7. Close doors you do not use
If nothing you run needs XML-RPC, block it at the web server so the request never reaches PHP:
location = /xmlrpc.php { return 403; }8. Update with a way back
wp db export - | gzip > before-update-$(date +%F).sql.gz
wp plugin update --all --dry-run
wp core update && wp core update-db
wp plugin update --all
wp core verify-checksumsKeep a copy of the files as well as the database, or better, deploy from Git so the previous version is always one step away. Then load the front page, a post, the login page and a form before you call it done.
Ten minutes a month on these saves a lot of firefighting. If you would rather not do it yourself, that is what managed hosting is for.