Blog / Maintenance Windows Done Right — Planned Downtime Without the Panic
maintenance status-page incidents uptime

Maintenance Windows Done Right — Planned Downtime Without the Panic

Planned maintenance shouldn't look like an outage — picking windows, pausing monitors, 503 + Retry-After, SLA carve-outs and a comms template that works.
The CompleteStatus Team · · 6 min read
Maintenance Windows Done Right — Planned Downtime Without the Panic
Want this checked continuously?
CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.
Monitor your site free

There are two kinds of downtime: the kind that happens to you, and the kind you schedule. The second kind should be boring — you picked the time, you know exactly what's changing, and you know when it ends. Yet plenty of teams manage to turn a routine database migration into something indistinguishable from an outage: users hit an unexplained error page, monitors scream, support tickets pile up, and the on-call engineer gets paged for work they're doing on purpose.

Planned maintenance done right is a communication and configuration exercise, not an engineering one. Here's the checklist.

Pick a window your traffic actually agrees with

"We'll do it Sunday at 2 AM" is a guess. Your analytics know the answer:

  • Find your real trough. Pull a month of traffic by hour and pick the window where requests bottom out. For a B2B tool that's often weekend mornings; for a consumer app it might be a weekday at 4 AM — and if your audience spans time zones, remember that 2 AM in New York is mid-morning in Berlin.
  • Check what else runs then. The classic self-inflicted wound: scheduling maintenance on top of your own nightly backup, billing run or report generation. Take the database down at 3 AM and the 3 AM backup job fails too — silently.
  • Avoid your own deadlines. No maintenance the night before a launch, during a marketing campaign, or on the last day of the month if your customers do end-of-month reporting against your API.
  • Size the window honestly, then pad it. Estimate the work, double it, and announce that. Finishing 40 minutes early makes you look competent; overrunning by 40 minutes makes you look out of control — even if the total elapsed time is identical.

Announce it before, not during

A maintenance window that users discover by hitting an error page is just an outage with paperwork. The status page is the tool for this:

  • Post the window ahead of time — a week ahead for anything customer-visible, 24–48 hours minimum. Include the start time with time zone, the expected duration, and what will be affected ("the dashboard will be unavailable; monitoring and alerting continue to run").
  • Remind people as it approaches. Status page subscribers should get the scheduled notice and a "starting now" update. For API customers, an email to technical contacts is worth the effort — their integrations are the thing that breaks.
  • Update when it's over. "Maintenance completed as planned" closes the loop and builds the habit — in users, of checking your status page; in you, of keeping it honest.

Pause your monitors — and set an alarm to unpause them

If you don't suppress monitoring during the window, you train your team to ignore alerts. The 3 AM page that's "just the maintenance" this month is the real outage you sleep through next month. So: pause or schedule a maintenance window on every monitor that touches the affected systems, including the indirect ones — the API check that depends on the database you're migrating.

But here's the sharper edge, and it bites constantly: forgetting to unpause. A paused monitor is a blind spot with no expiry date. Teams have shipped a maintenance window, gone to bed, and run for weeks with their most important check disabled — discovering it only when a real outage went unnoticed. Two defenses:

  • Use scheduled windows, not manual pauses. A window with an end time re-arms itself. A manually paused monitor waits for a human memory that has already moved on.
  • If you must pause manually, create the unpause reminder at the same moment — calendar event, ticket, alarm. Pausing and scheduling the unpause are one action, not two.

Return a real 503 — not a pretty 200

The maintenance page itself is where good intentions produce long-term damage. A friendly "we'll be back soon!" page served with HTTP 200 tells every machine that everything is fine: search engines index your maintenance page and can replace your real content in results, API clients treat the HTML as a valid response and corrupt whatever they were syncing, and any monitoring still running records "up."

The correct answer is 503 Service Unavailable with a Retry-After header — the status code that exists precisely for this. It tells crawlers "temporary, come back later" (Google has long documented 503 as the right signal for planned downtime), tells well-behaved clients when to retry, and tells the truth.

server {
    listen 443 ssl;
    server_name app.example.com;

    location / {
        return 503;
    }

    error_page 503 @maintenance;
    location @maintenance {
        root /var/www/maintenance;
        rewrite ^ /index.html break;
        add_header Retry-After 3600 always;
        add_header Cache-Control "no-store" always;
    }
}

Details worth getting right:

  • Retry-After: 3600 — seconds until you expect to be back. An HTTP date works too. Set it to the end of your announced window.
  • Cache-Control: no-store — the last thing you want is a CDN or browser caching the maintenance page past the window.
  • Keep the page self-contained. Inline the CSS and any image — if it loads assets from the app you just took down, it's a broken page, not a maintenance page.
  • For APIs, return 503 with a JSON body, not HTML — clients parsing an HTML string as JSON generate their own incident on the customer's side.

Put planned work in the SLA — in writing

If you've promised 99.9% uptime, that's about 43 minutes a month. One two-hour maintenance window blows the budget three times over — unless your SLA says it doesn't. Every serious SLA carves out planned maintenance, and the carve-out has teeth only if it's specific: how much notice you'll give (e.g., 72 hours), through what channel (the status page), and often a cap on total planned downtime per month. If your SLA is silent on maintenance, every window you run is technically an SLA breach you're hoping nobody measures. Fix the document before someone does.

A comms template you can steal

Subject: Scheduled maintenance — {date}, {start}–{end} {timezone}

What: {one sentence: what we're doing and why users benefit}
When: {date}, {start}–{end} {timezone} ({duration} window;
      actual downtime expected to be shorter)
Impact: {what will be unavailable / degraded; what keeps working}
Action needed: {usually "none"; for API users, note retry behavior}
Updates: {status page URL} — subscribe for start/finish notices

We'll post here when maintenance begins and again when it's complete.

Send it when you schedule the window, and let the status page handle the play-by-play.

Make planned downtime boring

That's the whole goal: a window your users knew about, a page that tells machines the truth, monitors that stay quiet during the window and re-arm themselves after it. CompleteStatus is built around exactly this workflow — scheduled maintenance windows that suppress alerts and automatically resume when the window ends (no forgotten-pause blind spots), plus hosted status pages with subscriber notifications so the announcement, the "starting now" and the "all clear" are one workflow instead of five tools. See everything included on the features page, or create a free account and schedule your next window properly.

Stop checking by hand

CompleteStatus runs these exact checks around the clock — uptime, SSL, DNS, security headers and SPF/DKIM/DMARC — and alerts you the moment something changes. One dashboard, one bill.
Start free Run a free check
Uptime is table stakes. We watch the rest — security headers, email authentication, certs and DNS, with the fix attached.
Start free
Company
© 2026 CompleteStatus. All rights reserved. CompleteStatus — operated in the United States · support@completestatus.com