Build an on-call rotation that engineers do not dread. Covers compensation, escalation design, runbook architecture, alert fatigue elimination, and the cultural patterns that separate healthy on-call from burnout factories.
This page describes how to build incident response practices that prevent burnout, reduce handoff chaos, and keep teams from feeling like they're constantly firefighting. It matters when an incident starts as a minor alert and becomes a multi-hour outage involving several engineers across multiple time zones. This is about systems design for sustained reliability, not just alert configuration.
Incidents should be classified by impact scope rather than technical cause:
Example classification logic in SQL:
SELECT
CASE
WHEN customer_impact = 'yes' THEN 'P0'
WHEN internal_impact = 'yes' THEN 'P1'
ELSE 'P2'
END AS incident_level
FROM alert_events
WHERE event_time > NOW() - INTERVAL '15 minutes';
Include timestamp, team, and service identifier in incident names:
INC-2023-10-15-0945-team-a-service-x
This format ensures searchability across systems. No dashboards or tools should require special naming conventions beyond this.
Escalation occurs when:
Each incident requires:
Example role assignment in a JSON incident log:
{
"incident_id": "INC-2023-10-15-0945-team-a-service-x",
"commander": "[email protected]",
"communications_lead": "[email protected]",
"technical_lead": "[email protected]"
}
Use markdown files with these sections:
Create a Slack channel with these settings:
#incidents-team-aUse consistent labels for alerts:
alertname="DatabaseConnectionTimeout"
severity="warning"
team="team-a"
service="web-api"
Alerts should fire when:
Example Prometheus rule:
groups:
- name: database-alerts
rules:
- alert: DatabaseTimeouts
expr: rate(db_connection_timeouts[5m]) > 0.01
for: 3m
labels:
severity: warning
team: team-a
When multiple alerts fire from the same source, keep only the first one:
Before leaving an incident, ensure:
Example handoff checklist:
## Handoff Checklist
- [ ] Document current status and open actions
- [ ] List all active alerts and their resolution state
- [ ] Note any pending communications with stakeholders
- [ ] Explain any ongoing experiments or changes
Each engineer should:
Use cron to send daily summaries:
#!/bin/bash
# /usr/local/bin/oncall-summary.sh
curl -X POST \
-H "Content-Type: application/json" \
-d '{"team": "team-a", "date": "'$(date +%Y-%m-%d)'"}' \
https://internal-api.example.com/oncall/summary
Every incident should produce:
Include these sections:
After each incident, create a GitHub issue for each improvement item:
# Example script to create follow-up issues
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-d '{
"title": "Add alert for database connection timeout",
"body": "This incident revealed a gap in our monitoring. We should add an alert to detect this issue earlier.",
"labels": ["monitoring", "incident-response"]
}' \
https://api.github.com/repos/team-a/service-x/issues
Use multiple signal sources before triggering:
When an alert is expected:
Example silence mechanism:
# Alert rule with silencing
- alert: HighCPUUsage
expr: rate(container_cpu_usage_seconds_total[5m]) > 0.8
for: 3m
labels:
severity: warning
team: team-a
silence_until: "2023-10-16T10:00:00Z"
Limit alerts to no more than 5 per engineer per hour:
SELECT
engineer,
COUNT(*) as alert_count
FROM alert_logs
WHERE event_time > NOW() - INTERVAL '1 hour'
GROUP BY engineer
HAVING COUNT(*) > 5;
Create a matrix of when to escalate:
Example Slack message template:
@incident-team: Incident [INC-2023-10-15-0945-team-a-service-x] has been escalated to P0.
Current status: [brief update].
Expected resolution: [time estimate].
Stakeholders: [list of people to notify].
Maintain a JSON file with:
{
"team": "team-a",
"primary_contact": "[email protected]",
"secondary_contact": "[email protected]",
"oncall_schedule": {
"monday": "alice",
"tuesday": "bob",
"wednesday": "charlie"
}
}
Measure these indicators:
Schedule quarterly reviews of:
After each incident, update:
Alerts can silently fail when:
Example silent failure: Prometheus alerts fire but Slack notifications are lost due to network issues.
Teams often confuse:
Incident logs can vary widely in format and completeness, leading to:
Some systems require specific tooling that isn't available when the incident occurs. For example, a service might depend on a dashboard that's down during the incident.
Teams often fail to:
When engineers are scheduled for:
They become less effective and more likely to miss issues.
The key to sustainable incident response is consistency, clarity, and regular process improvement. Teams that build these practices early avoid the common pitfall of reactive firefighting that leads to team exhaustion and poor reliability outcomes.
This page was rewritten on 15 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy