Stage 6 · Operate
On-Call Culture & Sustainability
Effective Handoffs
Shift handoff templates, context transfer, and knowledge sharing — no information lost between shifts.
Why Handoffs Matter
Poor handoffs cause incidents. The outgoing engineer knows things the incoming engineer does not — active issues, risky deploys, unusual behavior. Without a structured handoff, this knowledge is lost and the incoming engineer is blind.
A handoff is not just 'you are on-call now.' It is transferring context: what is happening, what to watch for, what was done recently, and what might break. Every piece of context that is not transferred is a risk.
Handoff Template
## On-Call Handoff: [Date]
### Shift Summary
- **Outgoing:** [name]
- **Incoming:** [name]
- **Shift:** [start time] to [end time]
### Active Incidents
- [Incident 1]: [Status, next steps, link to war room]
- [Incident 2]: [Status, next steps, link to war room]
### Recent Deployments
- [Service]: [version] deployed at [time] — [any issues?]
### Watch Items
- [Service X]: [unusual behavior observed, not yet an incident]
- [Metric Y]: [trending upward, monitor closely]
### Blockers or Risks
- [Risk 1]: [description and mitigation]
### Follow-Up Actions
- [Action 1]: [owner, due date]
### Environment Health
- [ ] All services healthy
- [ ] No disk space warnings
- [ ] No certificate expirations within 7 days
- [ ] No unusual traffic patternsActive Incidents
Active incidents during a handoff require special attention. Document the full context: what happened, what was done, what is the current state, and what the next steps are. The incoming engineer should be able to pick up the investigation without asking questions.
## Active Incident Handoff: INC-2024-0042
**Title:** High error rate on user-api
**Severity:** SEV2
**Started:** 2024-01-15 14:30 UTC
**Duration:** 2 hours 15 minutes
### What Happened
- Error rate spiked to 15% at 14:30 UTC
- Affected: /api/users, /api/sessions endpoints
- Root cause identified: database connection pool exhaustion
### What Was Done
- Scaled connection pool from 50 to 100
- Error rate dropped to 5% but not resolved
- Identified connection leak in /api/users endpoint
### Current State
- Error rate: 5% (target: < 1%)
- Connection pool: 85/100 in use
- Active connections not being released
### Next Steps
- Investigate connection leak in /api/users
- Check for slow queries holding connections
- Consider restarting pods to clear leaked connections
### Links
- Grafana: [link]
- Slack war room: #inc-2024-0115-user-api
- PagerDuty: [link]Context Transfer
Context transfer goes beyond active incidents. Share knowledge about system behavior, recent changes, known issues, and team decisions. This context helps the incoming engineer make better decisions.
context_categories:
system_behavior:
- "Expected traffic patterns for this time of day"
- "Known performance quirks or edge cases"
- "Recent scaling events or configuration changes"
recent_changes:
- "Deploys in the last 24 hours"
- "Infrastructure changes"
- "Configuration updates"
- "Database migrations"
known_issues:
- "Unresolved bugs that may surface"
- "Flaky tests or known instabilities"
- "Technical debt that increases risk"
team_decisions:
- "Why certain approaches were chosen"
- "Tradeoffs that were made"
- "Upcoming planned changes"Automated Handoffs
Automate handoff data collection. Generate reports of recent deployments, active alerts, system health, and capacity metrics. This reduces the manual burden and ensures nothing is missed.
#!/usr/bin/env bash
# Generate automated handoff report
REPORT_DATE=$(date +%Y-%m-%d)
REPORT_FILE="handoff-$REPORT_DATE.md"
cat > "$REPORT_FILE" << 'HEADER'
# Automated Handoff Report
HEADER
echo "## Recent Deploys (Last 24h)" >> "$REPORT_FILE"
kubectl get events -n production --field-selector reason=ScalingEvent \
--sort-by=.lastTimestamp | tail -10 >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "## Active Alerts" >> "$REPORT_FILE"
curl -s http://alertmanager:9093/api/v2/alerts | \
jq -r '.[] | "- **\(.labels.alertname)**: \(.status.state)"' >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "## System Health" >> "$REPORT_FILE"
echo "### CPU and Memory" >> "$REPORT_FILE"
kubectl top nodes >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "### Disk Usage" >> "$REPORT_FILE"
kubectl exec -n monitoring deployment/prometheus -- df -h /prometheus >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "### Certificate Expiry" >> "$REPORT_FILE"
echo "Check: https://grafana.internal/d/certificates" >> "$REPORT_FILE"
echo "Report generated: $REPORT_FILE"Post the handoff summary in a dedicated Slack channel. This creates a searchable record of handoffs and makes context available to the entire team, not just the incoming engineer.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.