503 Service Unavailable: the right way to go offline
503 Service Unavailable means the server is temporarily overloaded or down for maintenance; it’s the search-friendly code for planned downtime.
503 Service Unavailable means the server can’t handle the request right now because it’s overloaded or down for maintenance, and that it expects to recover. It’s the honest, search-friendly way to take a site offline briefly.
Definition
RFC 9110, section 15.6.4 describes a temporary overload or scheduled maintenance “which will likely be alleviated after some delay.” The server may send a Retry-After header (section 10.2.3) with a number of seconds or an HTTP date. The spec also notes that servers aren’t obliged to use 503 when overloaded; some simply refuse connections.
Why 503 is the right code for maintenance
A maintenance page served with 200 OK tells crawlers that “We’ll be back soon” is your content, and it can replace your real pages in the index. A 404 tells them the pages are gone. A 503 says “temporary, come back later.”
Google’s documentation groups 503 with other server errors: Googlebot slows down, keeps already indexed URLs for a while, and drops URLs that keep returning errors. So 503 protects you during short outages, not long ones. Google’s guide to reducing the crawl rate treats error codes as a tool for hours or a day or two. If maintenance will take longer, keep a read-only version of the site online instead.
Two details to get right:
- Know what happens to robots.txt. If it returns 503 too, Google treats the whole site as disallowed until it gets a normal answer. That pauses crawling during the outage, but make sure
robots.txtanswers 200 again the moment you’re back. - Don’t let the 503 be cached. Send
Cache-Control: no-storeso a CDN doesn’t keep serving it after you’re back.
Common causes of unplanned 503s
- Traffic spikes that exhaust PHP workers or app instances.
- Rate limiting that answers with 503 (Nginx
limit_reqdoes by default; 429 is the clearer choice). - Maintenance modes: WordPress, for example, serves a 503 “Briefly unavailable for scheduled maintenance” page while it updates.
- Load balancers with no healthy backends left.
How to serve a proper maintenance 503
Nginx
# inside the server block: touch /var/www/maintenance.on to switch on,
# delete it to switch off
if (-f /var/www/maintenance.on) { return 503; }
error_page 503 @maintenance;
location @maintenance {
root /var/www/errors;
rewrite ^ /maintenance.html break;
add_header Retry-After 3600 always;
add_header Cache-Control "no-store" always;
}
Apache (.htaccess)
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/maintenance.on -f
RewriteCond %{REQUEST_URI} !^/maintenance\.html$
RewriteRule ^ - [R=503,L]
ErrorDocument 503 /maintenance.html
Header always set Retry-After "3600" "expr=%{REQUEST_STATUS} == 503"
PHP
http_response_code(503);
header('Retry-After: 3600');
header('Cache-Control: no-store');
How to check
While maintenance is on, run a few URLs through the HTTP status checker and confirm they return 503, not 200 or a redirect to a maintenance URL. The HTTP header checker shows whether Retry-After and Cache-Control came through.
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Cache-Control: no-store
Content-Type: text/html; charset=utf-8 Frequently asked questions
How long can my site return 503 without losing rankings?
Keep it short. Google treats 503 as temporary, and its crawl-rate guidance talks about hours or a day or two. If URLs keep returning errors for longer, Google starts dropping them from the index.
Does Google respect the Retry-After header?
Google doesn’t document exactly how it uses Retry-After, and Googlebot slows down on any 503 anyway. Sending it costs nothing and helps other clients and crawlers that do honor it.
Should I redirect visitors to a maintenance page?
No. Serve the maintenance message with a 503 status at the original URLs. Redirecting to a separate maintenance URL with a 302 makes crawlers follow it to a 200 page, which defeats the purpose.