---
title: "Maintenance windows: silence alerts, keep checking · Fettle"
description: "How maintenance windows stop deploy alerts while checks keep running: one-off or recurring, timezones, uptime, and opening one from CI or an agent."
url: "https://fettle.sh/guides/maintenance-windows"
---

/ guides / maintenance-windows

# Maintenance windows: silence alerts, keep checking

How maintenance windows stop deploy alerts while checks keep running: one-off or recurring, timezones, uptime, and opening one from CI or an agent.

Updated 2026-10-31

[Start free](https://fettle.sh/register)

Free plan: 20 monitors every 3 minutes from 1 region. No card.

A maintenance window tells your monitoring that downtime in a given period is planned, so a deploy, a database upgrade or a reboot does not page anyone. Fettle is uptime monitoring for developers, and its maintenance windows keep checking every covered monitor but open no incident and send no alert while the window is in effect. Windows are one-off or recurring, follow your timezone through daylight saving changes, and are available from Pro. You can open one from the dashboard, the API (from CI right before a deploy) or an AI agent.

## What happens to a monitor during a maintenance window?

Checks keep running on their usual schedule and from the usual regions. Each result is stored and marked with the window that covered it, and the monitor's status still changes, so the dashboard shows a real DOWN if the deploy breaks something. What the window suppresses is the incident and every alert that would follow it: down, reminder and recovery.

If the monitor is still failing when the window ends, Fettle does not wait for a fresh streak of failures. The first failed check after the window opens an incident and sends the down alert, with the incident starting at that check, not at some point inside the window. A deploy that went wrong reaches you within one check interval of the window closing.

Two things a window does not suppress. SSL expiry warnings are not incidents, so they arrive as usual. And a window covers monitors, not heartbeats: pause the heartbeat of a job that will not run, as the [heartbeats docs](https://fettle.sh/docs/heartbeats) describe.

## Which monitors does a window cover?

Either the whole organization or a list of monitors. An organization-wide window covers every monitor, including ones created after the window. A monitor window covers only the monitors you pick, and needs at least one. There is no tag-based scope; to cover a group of monitors, select them in the form, or pass their ids through the API.

Several windows can overlap. A monitor is in maintenance when any enabled window that covers it is in effect.

## How do recurring maintenance windows work?

A window has a start, a length and, optionally, a repeat schedule. The dashboard builds the common ones: daily, weekly on the days you pick, monthly or yearly, every N of those, ending on a date, after a number of occurrences, or never. The API also takes less regular schedules, such as the last Friday of every month.

Hourly and minute-level frequencies are refused.

Each occurrence lasts from one minute to 28 days. Before you save a recurring window, the form, the API and the MCP tools can preview its next occurrences, so a schedule that lands on the wrong day shows up before it silences anything.

Editing a window keeps a history of its earlier schedules, and check results keep a reference to the window that covered them, so you can tell afterwards why an outage did not alert.

## How does a maintenance window handle timezones and daylight saving?

Every window runs in a named timezone, by default your organization's. The start is a local wall-clock time in that zone, and a repeating window keeps that local time: a weekly window at 03:00 on Sunday stays at 03:00 after the clocks change, rather than drifting to 02:00 or 04:00 the way a schedule kept in UTC would.

If you send the start through the API, send it without an offset or `Z` and name the zone in `timezone`. A start with an offset is refused instead of being guessed at.

## How does maintenance affect uptime and the status page?

Time inside a window counts as up. Fettle calculates uptime as observed time minus confirmed outages, and a window opens no outage, so planned downtime does not lower the figure on the dashboard, the API, badges or the status page. The [99.9% uptime guide](https://fettle.sh/guides/what-does-99-9-uptime-mean) explains what the figure measures.

On a [status page](https://fettle.sh/status-page), a component whose monitor is in maintenance shows "Maintenance" instead of an outage. The page banner shows maintenance too, unless another component is down or degraded at the same time, in which case the worse state wins.

## Pause or maintenance window: which one to use?

Use a maintenance window for planned work you expect to end: a deploy, a migration, a reboot. Use pause when you want a monitor to stop entirely, for example a service you are retiring. Pausing stops checks, closes any open incident without an alert, and stays in effect until someone resumes the monitor.

The practical differences:

- A paused monitor collects no data, so you cannot see whether the deploy actually broke anything, and the paused hours are left out of uptime rather than counted.
- A pause has no end. Forget to resume and the monitor stays silent through the next real outage. A window ends on its own, even when the CI job that opened it crashed halfway through.
- A window can cover the whole organization in one call. Pausing works monitor by monitor, or in bulk by id.

## How do I open a maintenance window from CI before a deploy?

Create a window with a write-scoped API key right before the deploy step, and delete it right after. `POST /v1/maintenance-windows` returns the window with its `id`; `DELETE /v1/maintenance-windows/{id}` ends it at once. Give the window a length a bit longer than your slowest deploy, so it still closes if the job dies before cleanup.

A GitHub Actions job that does this, with the key stored as a repository secret as [GitHub's guide to secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions) describes:

```
- name: Open a Fettle maintenance window
  id: maintenance
  env:
    FETTLE_API_KEY: ${{ secrets.FETTLE_API_KEY }}
  run: |
    start=$(jq -nr 'now - 60 | strftime("%Y-%m-%dT%H:%M:%S")')
    id=$(curl -fsS -X POST https://api.fettle.sh/v1/maintenance-windows \
      -H "Authorization: Bearer $FETTLE_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"name\": \"Deploy ${GITHUB_SHA::7}\", \"scope\": \"ORG\", \"dtstart\": \"$start\", \"timezone\": \"UTC\", \"duration_minutes\": 20}" \
      | jq -r .id)
    echo "id=$id" >> "$GITHUB_OUTPUT"

- name: Deploy
  run: ./deploy.sh

- name: Close the maintenance window
  if: always() && steps.maintenance.outputs.id != ''
  env:
    FETTLE_API_KEY: ${{ secrets.FETTLE_API_KEY }}
    WINDOW_ID: ${{ steps.maintenance.outputs.id }}
  run: |
    curl -fsS -X DELETE "https://api.fettle.sh/v1/maintenance-windows/$WINDOW_ID" \
      -H "Authorization: Bearer $FETTLE_API_KEY"
```

The start is a minute in the past so that a runner clock slightly ahead of Fettle's does not leave the first seconds of the deploy uncovered. `jq` computes it in UTC the same way on Linux and macOS runners, and the window id reaches the shell through `env` rather than being pasted into the script. To cover only the services being deployed, use `"scope": "MONITOR"` with `"monitor_ids": [...]`. A recurring window takes an extra `rrule` field. `GET /v1/maintenance-windows/active` lists what is silenced right now, which is handy as a check at the end of a pipeline.

Keys, scopes and the per-minute limit all of an organization's keys share are in the [API keys docs](https://fettle.sh/docs/api-keys); every endpoint is listed on the [uptime monitoring API](https://fettle.sh/api) page.

## Can an AI agent schedule maintenance for me?

Yes. Over MCP, an agent like Claude or Codex can create, preview, edit and delete windows with the same rules as the API: `create_maintenance_window`, `preview_maintenance_window`, `list_active_maintenance` and the rest. That makes "silence the API monitors while I run this migration" a sentence rather than a form:

```
Open a 45-minute maintenance window on every monitor tagged service:api, starting now.
Every Sunday at 03:00 Berlin time we restart the database for 30 minutes. Preview that
schedule, then save it as a maintenance window for the db monitors.
Is anything silenced right now?
```

The agent finds the monitors, previews a recurring schedule before saving it, and tells you what it created. Setup for Claude, Codex and other clients is in the [AI agents guide](https://fettle.sh/guides/uptime-monitoring-with-ai-agents).

## Limits worth knowing

Maintenance windows start on Pro; the [pricing page](https://fettle.sh/pricing) has the full plan comparison. A window does not cover heartbeats and does not suppress SSL expiry warnings. Recovery alerts are suppressed during a window like down alerts, so a monitor that fails and recovers inside the same window sends nothing at all. To check what reached your team outside maintenance, see [where alerts go](https://fettle.sh/guides/uptime-alerts-slack-discord-webhook). The rest of the cluster is in the [guides](https://fettle.sh/guides), starting from the [uptime monitoring overview](https://fettle.sh/uptime-monitoring).

## Questions

- Do checks stop during a maintenance window?

  No. Fettle keeps checking every covered monitor and records the results, marked with the window that covered them. Only incidents and alerts are suppressed while the window is in effect; nothing is queued for later.

- Does downtime during a maintenance window count against uptime?

  No. Time inside a window counts as up, because no incident opens there. If the monitor is still down when the window ends, an incident opens from the first failed check after it.

- Do maintenance windows cover heartbeats?

  No. A window covers monitors only. If a cron job will not run during planned work, pause its heartbeat before the work and resume it afterwards, so the missing ping does not alert.

## Related guides

- [What is uptime monitoring? A developer's guide Uptime monitoring checks your sites, APIs and jobs from outside on a schedule and alerts you when they stop answering. How checks, regions and alerts work.](https://fettle.sh/uptime-monitoring)
- [Set up uptime monitoring from Claude Code or Codex Connect Claude Code or Codex to Fettle over MCP, then let the agent create monitors and heartbeats, silence a deploy and triage an outage in the terminal.](https://fettle.sh/guides/uptime-monitoring-with-ai-agents)
- [Multi-region uptime checks: how regional consensus stops false alerts How multi-region uptime monitoring decides a site is down: why Fettle needs every fresh region to agree, what a partial failure shows, and the trade-off.](https://fettle.sh/guides/multi-region-monitoring)
- [API health check monitoring: design a /health endpoint worth watching How to design an API health check endpoint worth monitoring, from shallow vs deep checks to status codes, then watch it with status and keyword checks.](https://fettle.sh/guides/api-health-check-monitoring)
- [Uptime alerts in Slack, Discord or a webhook Send downtime alerts to Slack, Discord, Telegram or your own signed webhook: what triggers an alert, what stays quiet, and how repeats and recovery work.](https://fettle.sh/guides/uptime-alerts-slack-discord-webhook)
- [TCP port and DNS monitoring: checks below HTTP Watch databases, mail servers and SSH with TCP port checks, catch a database port left open to the internet, and alert when a DNS record changes.](https://fettle.sh/guides/tcp-port-and-dns-monitoring)
- [How to monitor an MCP server Check a remote MCP server with an HTTP POST that sends a real JSON-RPC request, and a local stdio server with a heartbeat behind a scheduled smoke test.](https://fettle.sh/guides/monitor-mcp-server)
- [What 99.9% uptime actually allows 99.9% uptime allows 43m 12s of downtime in a 30-day month. Budgets for every common target, and why your check interval limits what you can measure.](https://fettle.sh/guides/what-does-99-9-uptime-mean)

## Use cases

- [How to monitor a cron job with a heartbeat A cron job that stops running fails no request and throws no error. Here is how a heartbeat monitor catches the silence and alerts you before users notice.](https://fettle.sh/use-cases/cron-job-monitoring)
- [How to catch SSL certificate expiry before it hurts Renewal is automated and mostly works, which is exactly why nobody notices when it quietly stops. Here is what to monitor and how to get warned early.](https://fettle.sh/use-cases/ssl-expiry-monitoring)

## Start monitoring in a minute

The free plan checks up to 20 monitors as often as every 3 minutes from 1 region, and emails you when one breaks. See [pricing](https://fettle.sh/pricing) for the paid intervals, or follow the [quickstart](https://fettle.sh/docs/quickstart) to do it from the API.

[Start free](https://fettle.sh/register)
