How to Put WordPress in Maintenance Mode (The Right Way)

WordPress maintenance mode done right: manual .maintenance file, WP-CLI, plugin methods, and a custom maintenance page that doesn't embarrass clients.

Dobromir Dechev
Dobromir WordPress agency owner

Pushing a core update, a plugin change, or a theme tweak to a live WordPress site without a maintenance window is a gamble. If something goes wrong mid-update — a network drop, a plugin conflict, a failed database migration — visitors see a broken site, or worse, a half-rendered page with PHP errors. Maintenance mode takes the site offline in a controlled way so failures stay invisible. The problem is most WordPress sites use the default maintenance screen, which looks like it was designed in 2005 and gives clients nothing useful. This guide covers every method, from raw PHP to managed hosting tools, so you can pick the right one for the situation.


What WordPress maintenance mode actually does

When WordPress runs a core update, it automatically creates a file called .maintenance in the root of your installation. That file contains a single line of PHP:

<?php $upgrading = time(); ?>

WordPress checks for this file on every page load. If it exists and the timestamp inside it is less than 10 minutes old, WordPress serves a plain white page that reads: "Briefly unavailable for scheduled maintenance. Check back in a minute." Nothing else. No branding, no estimated time, no way to contact anyone.

After 10 minutes, WordPress ignores the file even if it is still there — this is a safety net to prevent a failed update from locking out the site permanently. WordPress deletes the file itself when the update completes successfully.

The problems with the default behaviour:

  • The default screen looks unprofessional for client sites
  • If an update fails partway through, the file may linger and confuse visitors
  • You have no control over what visitors see
  • There is no way to whitelist logged-in admins so you can work while the screen is up

The methods below give you full control over all of these.


Method 1 — Manual .maintenance file

This is the most reliable method because it works even if WordPress itself is broken — a corrupted plugin, a failed core update, a database that will not connect. All you need is FTP or SSH access.

Create the file:

Connect to your server and create a file named .maintenance in the WordPress root (the same folder as wp-config.php and wp-login.php). The file must contain exactly:

<?php $upgrading = time(); ?>

The time() call returns the current Unix timestamp. WordPress checks that this timestamp is less than 10 minutes old. If you hard-code a timestamp instead of using time(), maintenance mode will expire after 10 minutes regardless. Using time() means it stays active indefinitely until you remove the file.

Remove the file:

Delete .maintenance from the root when you are done. If you used FTP, just right-click and delete. If you used SSH:

rm /var/www/html/.maintenance

Replace /var/www/html/ with your actual document root.

Important note on the 10-minute timeout: WordPress's maintenance check in wp-includes/load.php does this:

if ( file_exists( ABSPATH . '.maintenance' ) ) {
    include( ABSPATH . '.maintenance' );
    if ( isset( $upgrading ) && ( time() - $upgrading ) < 10 * MINUTE_IN_SECONDS ) {
        wp_maintenance();
    }
}

Because we use time() in the file, time() - time() always equals 0, which is always less than 600. The site stays in maintenance mode until you physically remove the file.


Method 2 — WP-CLI

If you have shell access and WP-CLI installed (it is standard on most managed hosts and easy to install elsewhere), this is the fastest method:

# Enable maintenance mode
wp maintenance-mode activate

# Check current status
wp maintenance-mode status

# Disable maintenance mode
wp maintenance-mode deactivate

WP-CLI handles creating and deleting the .maintenance file for you. The status command tells you whether maintenance mode is currently active and how long it has been on.

Useful in combination with WP-CLI update commands:

# Put site in maintenance, run all updates, bring it back up
wp maintenance-mode activate
wp core update
wp plugin update --all
wp theme update --all
wp maintenance-mode deactivate

This approach gives you a scripted, repeatable update process. If anything fails, the site stays in maintenance mode so you can investigate before bringing it back up.

Running WP-CLI remotely with SSH:

ssh [email protected] "cd /var/www/html && wp maintenance-mode activate"

Or pipe the full update sequence as a one-liner if you handle multiple client sites.


Method 3 — Plugin

Plugins make sense when you need a custom-branded maintenance page with features like countdown timers, email capture, or subscriber notifications. Two plugins worth using:

WP Maintenance Mode (free, WordPress.org): Simple settings panel, lets you set a custom message, a countdown timer, and a contact form. Works well for straightforward needs.

Coming Soon Page & Maintenance Mode by SeedProd: More polished drag-and-drop builder, integrates with email marketing tools (Mailchimp, ConvertKit, etc.), good for client-facing launches where you want to capture leads during the build phase.

Key features to evaluate in any maintenance mode plugin:

  • Admin bypass — logged-in admins should see the live site, not the maintenance screen
  • Custom branding — client logo, brand colours, custom message
  • SEO handling — the plugin should serve a proper 503 Service Unavailable HTTP status with a Retry-After header so search engines know to come back rather than de-index the page
  • Countdown timer — sets expectations for visitors
  • Email capture — optional but useful for pre-launch sites
  • Whitelisted IPs — lets you allow specific IPs (your office, client's office) to see the live site

One thing to watch: many free maintenance mode plugins serve a 200 OK status on the maintenance page, which tells Google the page is normal content. This can damage SEO if maintenance runs for more than a few hours. Verify the HTTP status with curl -I yourdomain.com and make sure you see 503.


Build a custom maintenance page

If you want full control without a plugin, you can replace the default WordPress maintenance screen with a custom HTML page. Create a file at wp-content/maintenance.php. When this file exists, WordPress uses it instead of the built-in maintenance message.

Here is a clean, minimal maintenance page:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="robots" content="noindex, nofollow">
    <title>Under Maintenance — Back Shortly</title>
    <style>
        *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
            background: #0f172a;
            color: #e2e8f0;
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center;
            padding: 2rem;
        }

        .container {
            max-width: 480px;
        }

        .logo {
            font-size: 1.5rem;
            font-weight: 700;
            color: #f8fafc;
            margin-bottom: 2rem;
            letter-spacing: -0.025em;
        }

        h1 {
            font-size: 2rem;
            font-weight: 700;
            color: #f8fafc;
            margin-bottom: 1rem;
            line-height: 1.2;
        }

        p {
            font-size: 1rem;
            color: #94a3b8;
            line-height: 1.6;
            margin-bottom: 1.5rem;
        }

        .eta {
            display: inline-block;
            background: #1e293b;
            border: 1px solid #334155;
            border-radius: 8px;
            padding: 0.75rem 1.5rem;
            font-size: 0.875rem;
            color: #64748b;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="logo">Your Site Name</div>
        <h1>We'll be back shortly.</h1>
        <p>We're performing scheduled maintenance to improve the site. Everything is fine — we'll be back online within the hour.</p>
        <span class="eta">Estimated downtime: ~60 minutes</span>
    </div>
</body>
</html>

The <meta name="robots" content="noindex, nofollow"> tag is important. Combined with a proper 503 HTTP status (which WordPress sends automatically when the .maintenance file is present), this tells search engines not to index or follow links from the maintenance page.

Edit the logo, message, and estimated time to match the client's branding. For longer maintenance windows, add a contact email so visitors have somewhere to go.


How managed hosts handle maintenance

If you are on a managed WordPress host — Kinsta, Cloudways, WP Engine — you should rarely need to put the live site into maintenance mode at all.

Kinsta provides a full staging environment with every plan. You make all your changes on staging, test them, and push to live in one click from the MyKinsta dashboard. The push takes seconds and there is no window where the site is partially updated. Core updates can also be run from the dashboard with automatic backups before each update. If something breaks, you roll back to the pre-update snapshot in two clicks.

Cloudways has a built-in staging application for every server. The Cloudways Migrator and staging tools let you clone the live site to staging, apply updates, test, then push back to live. The push process handles file sync and database sync together, so you never have a mismatched state. The Cloudways dashboard also has a one-click maintenance mode toggle that serves a customisable page with a proper 503 status.

For agency work, this workflow — stage, test, push — eliminates most reasons to ever put a live site in maintenance mode. The only time you still need it is for database migrations or changes that genuinely cannot be tested on staging (payment gateway credentials, third-party integrations that only work on the live domain).


Was this article helpful?