
Most WordPress update failures happen in a narrow 2–10 minute window. PHP files change, caches serve a mix of old and new assets, and someone hits checkout at the worst moment. This WordPress maintenance mode tutorial shows a safer, production-friendly workflow for shared hosting (cPanel) or a VPS. You’ll get practical steps for backups, update order, cache control, and a rollback plan that won’t turn into an all-night incident.
You’re not building an elaborate staging pipeline. You’re creating a short, controlled maintenance window.
That window protects WooCommerce revenue, prevents broken admin sessions, and keeps downtime predictable.
What you’ll build (and what you won’t)
You’ll set up a short, controlled maintenance window with:
- A pre-flight checklist (backups, disk space, PHP version, plugin risk scan)
- A maintenance page that still allows logged-in admins (and optionally checkout)
- A clean update sequence and cache purge so users don’t see half-updated pages
- A fast rollback plan using files + database snapshots
You won’t build a staging site here. If you need staging, use a proper staging workflow.
This tutorial stays focused on production-safe updates when you must update in place.
Prerequisites (5 minutes)
- WordPress admin access
- SFTP/SSH or cPanel File Manager access
- A backup method you trust (host backups, restic, or cPanel backups)
- Maintenance window of at least 15 minutes
If you manage multiple sites or want tighter control, a VPS is usually less frustrating than shared hosting. HostMyCode’s HostMyCode VPS gives you predictable resources for updates, caching, and rollbacks.
Step 1: Pre-flight checks before you touch plugins
Skip pre-flight and your “quick update” turns into an incident.
1) Confirm you can roll back
At minimum, you need:
- A database backup made right now
- A files backup (at least
wp-content, and ideally the whole site)
2) Check disk space (common silent failure)
On a VPS, run:
df -h
du -sh /var/www /home/*/public_html 2>/dev/null | sort -h
On cPanel, open Disk Usage. Make sure you have room for a backup plus the update.
If you’re near quota, fix that first. Plugin unzips can fail mid-way and leave partial code behind.
3) Verify PHP version and extensions
In WordPress, go to Tools → Site Health → Info. Note:
- PHP version (aim for a supported stable line in 2026)
- Memory limit (128–256 MB is typical; WooCommerce admin often prefers 256 MB)
On cPanel, you can usually adjust PHP in MultiPHP Manager or Select PHP Version.
On a VPS, you change it directly.
4) Quick “risk scan” for your plugin set
Before updating, look for these red flags:
- Plugins that modify checkout, payment gateways, memberships, or caching
- Plugins with abandoned support or no updates in a long time
- Any custom code in
functions.phpthat references plugin functions directly
If you can’t tolerate checkout breakage, schedule a longer window.
Plan to test payment flows immediately after updates.
Step 2: Take a clean backup you can actually restore
Backups only matter if you can restore them quickly. Keep the process simple and repeatable.
Option A: cPanel (fastest for shared hosting)
- In cPanel, open Backup or Backup Wizard.
- Download a Home Directory backup (files).
- Download the MySQL database backup for your WordPress site.
If you manage a WHM server, set up remote, encrypted retention properly. Then leave it in place.
Do it once, then rely on it.
See remote destinations, retention, and encryption in WHM backups.
Option B: VPS (ssh + tar + mysqldump)
Adjust paths to your setup. Common WordPress docroots are /var/www/site or /home/USER/public_html.
# 1) Files backup
cd /var/www
sudo tar -czf /root/backups/site-files-$(date +%F).tar.gz site/
# 2) Database backup
mysqldump --single-transaction --quick --routines --triggers \
-u DBUSER -p DBNAME | gzip > /root/backups/site-db-$(date +%F).sql.gz
If you want automated, encrypted, offsite backups with restore tests, follow nightly restic backups on Ubuntu with a restore test.
Step 3: Put the site into maintenance mode (without locking yourself out)
WordPress does have a built-in maintenance mode during updates. It’s basic, and it can get stuck.
You want a switch you control.
Approach 1 (plugin): maintenance mode page + admin bypass
If you prefer a UI, use a reputable maintenance mode plugin that supports:
- Bypass for logged-in administrators
- Custom status code (usually
503) - Optional allow-list for specific URLs (like checkout)
Enable it, then verify in an incognito window.
Visitors should see the maintenance page, while you can still reach /wp-admin/.
Approach 2 (code): force a simple 503 in wp-config.php
This approach is predictable. It also avoids relying on a plugin that might be updating.
1) Create a file at wp-content/maintenance.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Maintenance</title>
<style>
body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;max-width:720px;margin:10vh auto;padding:0 18px;line-height:1.55}
.box{border:1px solid #ddd;border-radius:10px;padding:18px}
</style>
</head>
<body>
<div class="box">
<h1>Quick maintenance</h1>
<p>We’re applying updates and will be back shortly.</p>
<p>If you need urgent help, email support@yourdomain.tld.</p>
</div>
</body>
</html>
2) Add this near the top of wp-config.php (after <?php), and adjust the bypass rule if needed:
// Maintenance gate (remove after updates)
if (!defined('WP_CLI') && php_sapi_name() !== 'cli') {
$is_admin = (isset($_COOKIE['wordpress_logged_in_']) || is_user_logged_in());
$bypass_ip = 'YOUR.IP.ADDR.HERE';
$client_ip = $_SERVER['REMOTE_ADDR'] ?? '';
if (!$is_admin && $client_ip !== $bypass_ip) {
http_response_code(503);
header('Retry-After: 600');
$maintenance_file = __DIR__ . '/wp-content/maintenance.html';
if (file_exists($maintenance_file)) {
readfile($maintenance_file);
} else {
echo 'Maintenance';
}
exit;
}
}
Important: If your site sits behind a proxy/CDN, REMOTE_ADDR may be the proxy IP. In that case, use the maintenance plugin approach.
Or update the bypass logic to trust the correct header, but only if you control the proxy.
Step 4: Freeze change sources (cache, cron, and editors)
The update itself is only half the job. “Half-updated pages” usually come from caching or background tasks running at the wrong time.
1) Pause WP-Cron for 15 minutes (optional but helpful)
If your site does heavy scheduled work, add this temporarily to wp-config.php:
define('DISABLE_WP_CRON', true);
If you already use a real cron job, leave it alone. If you don’t, set one up later.
On cPanel, see how to run WordPress tasks via cPanel cron without triggering limits.
2) Clear or bypass server-side cache
- If you use LiteSpeed Cache: set it to “Development Mode” during updates.
- If you use Nginx FastCGI cache: purge the cache directory (or bypass with a cookie).
On an Nginx VPS with a FastCGI cache directory like /var/cache/nginx:
sudo systemctl reload nginx
sudo rm -rf /var/cache/nginx/*
Only run this if you actually configured caching there.
Don’t delete directories “just in case.”
3) Tell your team to stop editing
Edits during plugin updates can trigger “missing block” errors and messy revisions.
Make the window clear. No new posts, no page builder tweaks, and no settings changes.
Step 5: Run updates in a safer order
Order matters. Themes and plugins often assume a certain core version.
- Update WordPress core (if needed)
- Update your theme (or child theme last if it contains customizations)
- Update critical plugins one at a time (security, page builder, WooCommerce, payment gateways)
- Update everything else in small batches
Use WP-CLI on a VPS (cleaner than the browser)
WP-CLI avoids browser timeouts. It also gives you errors you can actually read.
# Go to the site root
cd /var/www/site
# See what needs updating
wp core check-update
wp plugin list --update=available
wp theme list --update=available
# Update core (if needed)
wp core update
# Update plugins one by one (example)
wp plugin update woocommerce
wp plugin update wordfence
# Update remaining plugins
wp plugin update --all
# Update themes
wp theme update --all
If WP-CLI throws a fatal error, stop and roll back.
Don’t keep pushing updates and hope the site “settles.”
On cPanel/shared hosting (browser-based updates)
- Use a single admin session in one browser tab.
- After each major plugin update, reload the frontend once and confirm
/wp-admin/still loads. - If a plugin update hangs, wait 2–3 minutes, then check the plugin folder via File Manager/SFTP before retrying.
Step 6: Fix the two most common post-update breakages
If the site looks “broken” right after updates, it’s usually one of these two issues.
1) White screen / 500 error (PHP fatal)
On a VPS, check your PHP-FPM and web logs immediately:
# Nginx + PHP-FPM examples
sudo tail -n 80 /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm --no-pager -n 80
On cPanel, open Metrics → Errors. Also check the site’s error_log in the docroot.
Quick isolation path:
- Rename the last-updated plugin folder:
wp-content/plugins/plugin-name→plugin-name.off - Reload the site
- If it comes back, you found the offender
2) “Mixed assets” and broken layout (cache mismatch)
Purge all layers in this order:
- Plugin cache (LiteSpeed/Redis cache plugin)
- Server cache (Nginx FastCGI cache if used)
- CDN cache (if enabled)
- Browser hard refresh (Ctrl/Cmd+Shift+R)
If your stack uses Redis object cache, verify it’s healthy.
You can also follow Redis object cache setup and troubleshooting for a stable baseline.
Step 7: Validate the site like a host, not like a casual editor
Don’t stop at the homepage. Check the pages that earn money.
Also check the pages most likely to fail.
Checkout and account checklist (WooCommerce sites)
- Add a product to cart
- Open checkout page
- Test payment gateway in sandbox/test mode if available
- Confirm order emails are sent (and not stuck)
If emails fail, you’ll often hear about it as “orders not confirmed” within hours.
Keep this link handy: fix SPF/DKIM/rDNS and SMTP errors for reliable mail.
Admin checklist (fast detection)
- Log in to
/wp-admin/and open Plugins page - Open Site Health and confirm no fatal issues
- Open a few editor screens (Posts, Pages, Products)
- Check that media uploads work (common permissions problem)
Step 8: Turn maintenance off cleanly (and prevent “stuck maintenance”)
If you used the wp-config.php gate:
- Remove the maintenance block you added
- Remove
define('DISABLE_WP_CRON', true);if you set it temporarily
If WordPress gets stuck in built-in maintenance mode, delete the file:
rm -f /path/to/wordpress/.maintenance
Finish with one last cache purge. Then re-check checkout and login pages.
Step 9: Rollback plan (files + database) you can execute in 10 minutes
A rollback isn’t a defeat. It’s how you keep downtime short and keep orders flowing.
Rollback on a VPS (example)
1) Put maintenance mode back on (so users don’t write data mid-restore).
2) Restore files:
cd /var/www
sudo mv site site.broken.$(date +%F-%H%M)
sudo mkdir site
sudo tar -xzf /root/backups/site-files-YYYY-MM-DD.tar.gz -C /var/www/site --strip-components=1
3) Restore database:
gunzip -c /root/backups/site-db-YYYY-MM-DD.sql.gz | mysql -u DBUSER -p DBNAME
4) Clear cache, restart PHP-FPM if needed, and verify.
Rollback on cPanel
- Restore Home Directory backup (or at least
wp-contentvia File Manager) - Restore the database backup in phpMyAdmin (import)
If you run cPanel/WHM at server level, build restore practice into your routine.
A backup you’ve never restored is still a question mark. See how to run WHM restore tests without downtime.
Performance and security quick wins to do right after updates
Once the site is stable, spend five more minutes reducing the odds of the next outage.
- Update SSL/TLS settings after major web server changes. Use TLS hardening on Nginx/Apache as your baseline.
- Confirm AutoSSL/Let’s Encrypt renewals so checkout doesn’t break later. If renewals fail, follow SSL renewal troubleshooting for cPanel and VPS.
- Enable a simple uptime check for checkout and wp-login pages. See external monitoring + on-server health endpoints.
Common pitfalls (and the exact symptom you’ll see)
- Updating everything at once → you can’t identify what broke; rollback becomes the only move.
- No disk space during unzip → plugins disappear mid-update; site throws missing class errors.
- Cache not purged → CSS/JS mismatch, layout breaks, “random” errors that vanish later.
- Payment gateway updated without test → orders fail quietly; you notice hours later.
If your WordPress site handles orders or bookings, you need hosting that can absorb maintenance work without slowing to a crawl. Consider a managed VPS hosting plan for cleaner maintenance windows, backups, and quick rollbacks, or start with a flexible HostMyCode WordPress hosting stack if you prefer fewer moving parts.
FAQ
Should maintenance mode return 503 or 200?
Use 503 Service Unavailable for planned maintenance. It tells search engines the downtime is temporary and supports a Retry-After header.
Can I allow WooCommerce checkout during maintenance?
Yes, but be careful. If plugin updates touch checkout, allowing it can create partial orders. If you allow it, keep the window short and test a full order immediately after.
What’s the fastest way to identify which plugin broke the site?
Disable the last-updated plugin by renaming its folder in wp-content/plugins/. If the site recovers, you’ve isolated the cause in under a minute.
How often should I run plugin updates in 2026?
Weekly is a practical baseline for most sites, with emergency updates applied sooner. The key is consistency and a repeatable maintenance procedure, not hero debugging.
Summary: your repeatable maintenance window
Run the same sequence every time: pre-flight checks → fresh backups → controlled maintenance gate → update in order → purge caches → validate checkout/admin → remove maintenance → note what changed.
If you manage multiple production sites, a VPS makes this process easier to repeat. It’s even smoother on a HostMyCode VPS where you can use WP-CLI, snapshots, and predictable performance.