How to set up WordPress maintenance mode without hurting SEO
For maintenance that hides the site from visitors, WordPress should answer every request with HTTP status 503 and a Retry-After header. A 503 tells crawlers the outage is temporary and to come back later. A maintenance page served with status 200 tells them your pages have been replaced by a "back soon" message.
WordPress already does this correctly during its own updates. The risk comes from maintenance and coming-soon plugins, some of which show their page with a 200 status, and from leaving any maintenance mode on for days.
Step by step
1. Know what WordPress does by itself
While core, a plugin or a theme is updating, WordPress writes a .maintenance file in the site root. Every request then gets status 503, the header Retry-After: 600, and the message "Briefly unavailable for scheduled maintenance. Check back in a minute." WordPress ignores the file once it is more than ten minutes old, so a crashed update cannot lock the site forever. If an update fails and the message stays, delete .maintenance over FTP.
2. Brand the built-in screen
Create wp-content/maintenance.php. When that file exists, WordPress loads it instead of the default message. Because your file replaces the default handler, send the headers yourself at the top:
<?php
header( 'HTTP/1.1 503 Service Unavailable' );
header( 'Retry-After: 600' );
header( 'Content-Type: text/html; charset=utf-8' );
?>
<!doctype html>
<title>Back shortly</title>
<h1>We are updating the site</h1>
<p>This usually takes a few minutes. Thanks for waiting.</p>
It runs before themes and plugins load, so keep it to plain HTML.
3. Turn on maintenance mode on purpose
For planned work longer than an update, add this to a small plugin and activate it when needed:
add_action( 'template_redirect', function () {
if ( current_user_can( 'manage_options' ) || is_robots() ) {
return;
}
header( 'Retry-After: 3600' );
wp_die(
'<h1>Scheduled maintenance</h1><p>We will be back within the hour.</p>',
'Maintenance',
array( 'response' => 503 )
);
} );
Administrators still see the real site, robots.txt keeps answering, and everyone else gets the 503 page. Retry-After is in seconds. Set it to a realistic estimate.
4. If you use a maintenance plugin, test its status code
Activate it, then from a terminal, logged out:
curl -sI https://example.com/ | grep -iE "^HTTP|^retry-after"
curl -sI https://example.com/a-post/ | grep -iE "^HTTP"
Both must show 503. If you see 200, look for a setting named something like "send 503" or "maintenance" as opposed to "coming soon". Coming-soon modes are designed for sites that have not launched and often answer 200 on purpose. If you see a 302 to a /maintenance/ page, every URL on the site is being redirected to one page, which is worse.
5. Leave robots.txt reachable
Do not block the site in robots.txt for the duration, and keep /robots.txt itself out of the 503 if you can. WordPress fires template_redirect for its virtual robots.txt too, which is why the snippet above skips the request when is_robots() is true. Google's documentation says that when robots.txt returns a server error, it treats the site as temporarily off limits. During core's own update window this cannot be avoided, and at ten minutes it does not matter.
6. Keep it short and switch it off completely
Google documents that 503 responses are fine for temporary downtime and that URLs which keep returning server errors for an extended time are eventually dropped from the index. Plan maintenance in hours. For anything that needs days, work on a staging copy and swap it in. When you finish, deactivate the plugin or snippet, purge every cache, and run the curl commands again to confirm 200.
Why a 200 maintenance page is harmful
With a 200 status, each URL Google crawls during the outage appears to have new content: one short message, identical on every page. Google can index that text in place of your pages, or classify the URLs as soft 404s because they all look empty. Recovery then depends on each URL being recrawled. A 503 avoids all of this, because nothing is indexed from an error response.
Caches and CDNs
A page cache or CDN can keep serving your normal pages during maintenance, which is often what you want: visitors see the cached site while you work. It can also cache the maintenance page and keep serving it after you finish. Most caches do not store 503 responses, but check yours, and purge after switching maintenance off. If your CDN offers an "always online" feature, it may serve stale copies instead of the 503, which is harmless.
Common questions
Does maintenance mode affect SEO?
A short outage answered with 503 does not. Problems start when the maintenance page returns 200, when every URL is redirected to one page, or when the 503 stays for days.
How long can a site return 503 safely?
There is no published number. Google says persistent server errors lead to URLs being dropped, so keep outages to hours and use a staging site for long projects.
What is the .maintenance file in WordPress?
A temporary file WordPress creates in the site root during updates. While it exists and is less than ten minutes old, the site answers 503 with a maintenance message.