Escalation policies

An escalation policy is a stack of levels. Level 0 is the initial page (already handled by the layer rotation). Levels 1+ fire if the incident isn't acknowledged within delay_minutes of the previous level.

Mental model

text
0:00 Incident created. Primary on-call paged via Slack channel + @-mention.0:05 No ack yet. Level 1 fires → @-mention CTO directly.0:15 Still no ack. Level 2 fires → post to #incident-major channel.

Each level has:

  • Delay — minutes after the previous level
  • Target typeuser (specific person) / schedule (current on-call of another schedule) / channel (Slack channel)
  • Target — the user/schedule/channel id

Acking the incident (via dashboard, Slack button, or /happyuptime ack) stops escalation immediately.

Setup

1

Open the schedule's Escalation modal

On-Call → Schedules → click Escalation on the schedule card.

2

Add level 1

Click Add level. Default values: level 1, 5 min delay.

Pick the target:

  • Specific user — fires a Slack DM to that user.
  • Another schedule — resolves the current on-call of the target schedule and pages them.
  • Slack channel — broadcasts to the channel.

Save.

3

Add more levels (optional)

Add level 2 with a longer delay (e.g. 15 min) targeting a wider audience or a different person.

How the timer fires

A cron (every minute) walks oncall_escalation_state rows where resolved = 0. For each:

  1. Look up the next level's delay_minutes.
  2. If now - last_escalated_at >= delay_minutes, fire that level + bump current_level.
  3. If the incident has been acknowledged or resolved, mark resolved = 1 and skip.

Escalation state starts when an auto-incident is created (only if the project has at least one schedule with a policy).

Escalating manually

Slack alert messages have an Escalate button. Clicking it calls escalateIncident() directly — bumps the level and notifies the next target without waiting for the timer.

API

text
GET /oncall/schedules/:id/escalation # list policy levelsPOST /oncall/schedules/:id/escalation # upsert a levelDELETE /oncall/schedules/:id/escalation/:pid # delete a level

Patterns

  • Level 1 (after 5 min): page the engineering manager directly.
  • Level 2 (after 15 min): post to #incident-major channel for full team awareness.
  • Level 1 (after 10 min): target the "Backup On-Call" schedule. Resolves to the current on-call of that schedule, so the backup person rotates without you having to update the policy.

Use longer delays (30 min, 60 min) for lower-priority schedules where waking up the team mid-night isn't justified.

Ask a question... ⌘I