~learn.
?

Day 0535 minPreface+60 XP

Incident Management.

System Design Mastery Series — Production Readiness and Operational Excellence

4 stages5 code

watch it first · newThe whole lesson in a 18-minute animated lecture5 quiz checkpoints · ask the AI about any moment · captions, chapters and speed

Preface · 1 min

Preface#

You've built everything right. SLOs defined. Observability in place. Safe deployments. Capacity planned.

And yet, at 3 AM on a Tuesday, your phone still rings.

The incident

3:17 AM. Your phone buzzes.

PAGERDUTY: [CRITICAL] Payment service - Error rate 45%

Your heart rate spikes. You're awake now.

What happens next determines
  • How long customers are affected
  • How much revenue is lost
  • Whether this becomes a headline
  • Whether you learn and improve
  • Whether it happens again
Bad incident response
  • Panic
  • Blame
  • Multiple people changing things at once
  • No communication
  • "Fixed" but nobody knows how
  • Happens again in a month
Good incident response
  • Calm, structured approach
  • Clear roles and responsibilities
  • Coordinated troubleshooting
  • Stakeholders informed
  • Root cause identified
  • Systemic fix implemented
  • Lessons shared widely

The difference is not luck. It's preparation.

Today, we learn to handle the inevitable failures — and more importantly, to learn from them.

ExplainerThe whole lesson: incident management

At 3:17 AM the payment service's error rate hits 45%, and preparation, not luck, decides whether the response is calm and structured or panicked: 5% errors against a 1% SLO is an incident, and severity from SEV1 (over $10K an hour, all hands) to SEV4 sets the response. An incident runs detect, triage, respond, mitigate, resolve and learn (SEV1 targets: detect within 5 minutes, engage within 15, mitigate within an hour), with an incident commander who coordinates, a technical lead, a communications lead, mitigation before root cause, updates every 15 minutes and a status page within 10. Blameless postmortems use five whys (down to missing N+1 detection) and owned action items within 48 hours, and on-call stays sustainable with at least 8 people and fewer than 5 pages a shift.

Part I · Stage 1 of 4 · 17 min

Part I: Foundations#

Chapter 1: Incident Response Fundamentals#

1.1 What Is an Incident?#

Incident definition

An incident is an unplanned disruption or degradation of service that requires an immediate response.

NOT every alert is an incident
Alert Classification
"CPU usage at 75%" Monitoring, not incident
"Error rate 0.5% (SLO: 1%)" Warning, not incident
"Error rate 5% (SLO: 1%)" INCIDENT
Severity levels
Level Description Revenue impact Response Communication Example
SEV 1 - CRITICAL Complete service outage affecting all users > $10,000/hour Immediate, all-hands Exec notification, status page Checkout completely down
SEV 2 - HIGH Major feature degraded or subset of users affected $1,000-$10,000/hour Immediate, on-call + backup Internal stakeholders Payment processing slow (2x latency)
SEV 3 - MEDIUM Minor feature degraded, workaround exists < $1,000/hour Business hours OK Team notification Order history page slow
SEV 4 - LOW Minor issue, no user impact None Normal ticket queue None required Internal tool slightly degraded
Your turn · checkpoint 1not answered

Trade-off: fix it properly, or stop the bleeding?

It's 3:17 AM and the payment service is failing 45% of requests. A deploy went out an hour ago, and one engineer is sure they can find and patch the real bug in about 40 minutes. Do you let them, or roll back now without knowing the cause?

Think it through, or jot it down. Then compare.

One strong answer

  • Roll back now. The first job is to stop user impact. Every minute spent on the root cause is another minute of failed payments.
  • Mitigation doesn't have to be the real fix. Impact stops (time to mitigate); the full fix can come later (time to resolve), and that's fine.
  • The root cause still gets found, just after users are safe, and the postmortem makes sure it doesn't happen again.

1.2 Incident Lifecycle#

DiagramIncident lifecycle
%% title: Incident lifecycle
%% steps:
%% D: Detection: how we know something is wrong
%% D --> T: Triage: assess severity and assign people
%% T --> R: Response: coordinate the fix
%% R --> M: Mitigation: stop the bleeding first
%% M --> RS: Resolution: confirm the service is restored
%% RS --> P: Post-incident: learn and improve
flowchart TD
  D["1. DETECTION<br/>How we know something is wrong"]:::bad
  T["2. TRIAGE<br/>Assess severity and assign resources"]:::service
  R["3. RESPONSE<br/>Coordinate the fix"]:::core
  M["4. MITIGATION<br/>Stop the bleeding"]:::hot
  RS["5. RESOLUTION<br/>Confirm service is restored"]:::ok
  P["6. POST-INCIDENT<br/>Learn and improve"]:::service
  D --> T --> R --> M --> RS --> P
  1. Detection: how we know something is wrong
  2. Triage: assess severity and assign people
  3. Response: coordinate the fix
  4. Mitigation: stop the bleeding first
  5. Resolution: confirm the service is restored
  6. Post-incident: learn and improve
  • Detection: Automated alerts (preferred) · Customer reports · Internal reports
  • Triage: What is the impact? · Who is affected? · What's the severity level? · Who needs to be involved?
  • Response: Assign roles (IC, Comms, Technical) · Diagnose the issue · Implement mitigation · Communicate status
  • Mitigation: Restore service (rollback, failover, etc.) · May not be a complete fix · Priority: users over root cause
  • Resolution: Verify metrics are normal · Confirm no ongoing impact · Stand down responders
  • Post-incident: Write postmortem · Identify root cause · Create action items · Share learnings
Key metrics
Metric Question Target
TTD (Time to Detect) How long until we knew? < 5 minutes for SEV1
TTE (Time to Engage) How long until someone started working? < 15 minutes for SEV1
TTM (Time to Mitigate) How long until impact stopped? < 1 hour for SEV1
TTR (Time to Resolve) How long until fully fixed? May be longer than mitigation (that's OK)
ExplainerIncident timeline: detect, engage, mitigate, resolve

v2.3.1 deploys at 14:30 and errors climb from 14:35. The alert fires at 14:42 (time to detect: 7 min), on-call engages at 14:45 (3 min), a rollback started at 14:55 mitigates by 15:00 (18 min from detection), and the service is confirmed restored at 15:15: 40 minutes in all.

Your turn · checkpoint 2not answered

Design it: who does what in a SEV1?

Five engineers jump into the incident channel, all eager to help. The status page hasn't been updated and two of them are already changing config. How would you organise these five people?

Think it through, or jot it down. Then compare.

One strong answer

  • One Incident Commander coordinates, makes or delegates decisions, and knows who is doing what. They don't debug.
  • One Technical Lead diagnoses and proposes mitigations; only changes they've agreed run, one at a time and announced first.
  • One Communications Lead updates the status page and stakeholders. The rest act as experts the Technical Lead calls on, not as five parallel fixers.

1.3 Incident Roles#

Incident response roles
Incident Commander (IC)

The single point of coordination.

Responsibilities:

  • Declare incident severity
  • Coordinate response efforts
  • Make decisions (or delegate clearly)
  • Ensure communication is happening
  • Know who's doing what
  • Decide when incident is resolved

NOT responsible for:

  • Debugging the issue themselves
  • Making all technical decisions
Technical Lead

Leads the technical investigation.

Responsibilities:

  • Diagnose the root cause
  • Propose mitigation options
  • Implement or delegate fixes
  • Keep IC informed of progress
  • Verify fix is effective
Communications Lead

Manages stakeholder communication.

Responsibilities:

  • Update status page
  • Notify internal stakeholders
  • Draft customer communications
  • Keep timeline of events
  • Handle incoming questions
Subject Matter Experts (SMEs)

Brought in as needed for specific expertise.

Examples:

  • Database expert for DB issues
  • Payment team for payment issues
  • Security team for security incidents
  • Vendor contacts for third-party issues

For smaller incidents (SEV3/4): One person may fill multiple roles.

For larger incidents (SEV1/2): Clear role separation is critical.

Your turn · checkpoint 3not answered

What breaks with three people and 50 pages a week?

Your team's on-call rotation has three engineers, and the pager fires about 50 times a week, mostly for things that fix themselves. What happens to the team over the next few months, and to the one page that really matters?

Think it through, or jot it down. Then compare.

One strong answer

  • Each person is on call one week in three and is woken several times a night, so tiredness and burnout follow, then people leave.
  • When most pages are noise, people stop trusting the pager; the real page gets slow responses or is ignored.
  • The fix: a rotation of at least eight, a target of fewer than 5 pages a shift, and every alert actionable, urgent and backed by a runbook.

Chapter 2: On-Call Best Practices#

2.1 On-Call Structure#

On-call rotation design

Rotation structure

Primary on-call
  • First responder for all alerts
  • Available 24/7 during shift
  • Response time: < 15 minutes
  • Rotation: 1 week typical
Secondary on-call
  • Backup if primary unavailable
  • Escalation for complex issues
  • Response time: < 30 minutes
  • Less interrupted (only if needed)
Manager escalation
  • For SEV1 incidents
  • Business decisions
  • Customer communication approval

Sustainable on-call

Rules for healthy on-call
  • Minimum 8 people in rotation (Max 1 week in 8 weeks on-call)
  • Target: fewer than 5 pages per week-long shift (Google's SRE book caps on-call at 2 incidents per 12-hour shift)
  • Compensatory time off after busy shifts
  • No on-call during vacation/PTO
  • Handoff meetings between shifts
  • Regular review of on-call load
Warning signs
  • Same person on-call every week
  • Consistently 5+ pages per week
  • On-call during vacation
  • Burnout, turnover
  • People avoiding on-call duties

2.2 Alert Design for On-Call#

pythonAlertSeverity · 162 lines
# incident/alerting.py

"""
Alert design for effective on-call.

Good alerts are actionable and important.
Bad alerts cause fatigue and get ignored.
"""

from dataclasses import dataclass
from typing import List, Optional
from enum import Enum


class AlertSeverity(Enum):
    PAGE = "page"          # Wake someone up
    NOTIFY = "notify"      # Slack/email during business hours
    LOG = "log"            # Just log it


@dataclass
class AlertDefinition:
    """A well-designed alert."""
    name: str
    description: str
    severity: AlertSeverity
    
    # The query/condition
    condition: str
    
    # How long condition must be true before alerting
    duration: str
    
    # Runbook for responders
    runbook_url: str
    
    # Who to notify
    notify_channel: str
    
    # Tags for filtering
    tags: List[str]


# =============================================================================
# GOOD ALERT EXAMPLES
# =============================================================================

GOOD_ALERTS = [
    # This alert is ACTIONABLE and IMPORTANT
    AlertDefinition(
        name="CheckoutErrorRateHigh",
        description="Checkout error rate exceeds SLO, customers cannot complete purchases",
        severity=AlertSeverity.PAGE,
        condition='sum(rate(checkout_errors_total[5m])) / sum(rate(checkout_requests_total[5m])) > 0.01',
        duration="5m",
        runbook_url="https://wiki/runbooks/checkout-errors",
        notify_channel="payments-oncall",
        tags=["checkout", "revenue", "sev1"]
    ),
    
    # This alert has clear user impact
    AlertDefinition(
        name="APILatencyP99High",
        description="API p99 latency exceeds 1 second, users experiencing slow responses",
        severity=AlertSeverity.PAGE,
        condition='histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 1',
        duration="10m",
        runbook_url="https://wiki/runbooks/high-latency",
        notify_channel="api-oncall",
        tags=["latency", "user-experience"]
    ),
    
    # This is a WARNING, not a page
    AlertDefinition(
        name="DiskSpaceLow",
        description="Disk space below 20%, will need attention soon",
        severity=AlertSeverity.NOTIFY,
        condition='(node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.2',
        duration="30m",
        runbook_url="https://wiki/runbooks/disk-space",
        notify_channel="infrastructure",
        tags=["disk", "capacity"]
    ),
]


# =============================================================================
# BAD ALERT EXAMPLES (DON'T DO THIS)
# =============================================================================

BAD_ALERTS = """

❌ BAD: No runbook
   AlertDefinition(
       name="SomethingWrong",
       runbook_url=None  # Responder has no idea what to do
   )

❌ BAD: Too sensitive
   AlertDefinition(
       condition='error_count > 0',  # Any single error pages someone
       duration="0m"  # No buffer for transient issues
   )

❌ BAD: Not actionable
   AlertDefinition(
       name="CPUHigh",
       condition='cpu > 80%',  # So what? What should they do?
       # High CPU might be fine if latency is OK
   )

❌ BAD: Missing context
   AlertDefinition(
       name="Error",
       description="An error occurred"  # Which error? Where? Impact?
   )

❌ BAD: Pages for non-urgent issues
   AlertDefinition(
       name="SlowBackgroundJob",
       severity=AlertSeverity.PAGE,  # This can wait until morning
       description="Nightly report generation is slow"
   )

"""


# =============================================================================
# ALERT REVIEW CHECKLIST
# =============================================================================

ALERT_REVIEW = """
Before adding an alert, ask:

1. IS IT ACTIONABLE?
   □ Is there a runbook?
   □ Can the on-call actually fix it?
   □ Or do they just have to wait?

2. IS IT URGENT?
   □ Does it need to wake someone up?
   □ Or can it wait until morning?
   □ What's the actual user impact?

3. IS IT CLEAR?
   □ Does the name explain the problem?
   □ Does the description explain the impact?
   □ Can someone unfamiliar understand it?

4. IS THE THRESHOLD RIGHT?
   □ Will it fire for real problems?
   □ Will it fire for non-problems? (false positives)
   □ Is the duration appropriate?

5. DOES IT REDUCE NOISE?
   □ Can it be consolidated with similar alerts?
   □ Is it duplicating another alert?
   □ Will it cause alert fatigue?

If you can't answer YES to all of these,
the alert needs more work.
"""

2.3 On-Call Handoff#

On-call handoff process

The handoff between shifts is critical. Information lost in handoff causes longer incidents.

Handoff meeting agenda (15-30 minutes)
  1. Active issues (5 min)
    • Any ongoing incidents?
    • Any degraded services?
    • Any issues being monitored?
    • Handoff ownership of active issues
  2. Recent incidents (5 min)
    • What happened this week?
    • Any patterns or recurring issues?
    • Any postmortems needed?
    • Share context that might help
  3. Upcoming risks (5 min)
    • Scheduled deployments?
    • Maintenance windows?
    • Expected traffic spikes?
    • Anything to watch for?
  4. Tooling/access check (5 min)
    • VPN working?
    • PagerDuty configured?
    • Access to dashboards?
    • Runbooks accessible?
  5. Questions/concerns (5 min)
    • Anything unclear?
    • Any gaps in knowledge?
    • Contact info confirmed?
Handoff document template
markdown16 lines
Week of: [DATE]
Outgoing: [NAME]
Incoming: [NAME]

## Active Issues
- [None / List of issues with status]

## Recent Incidents
- [DATE] SEV2: [Brief description] - [Status: Resolved/Monitoring]

## Upcoming Risks
- [DATE] Deployment of [service]
- [DATE] Marketing campaign expected to increase traffic 2x

## Notes
- [Anything else the incoming person should know]
Quick check3 questions · +5 XP each

Incident roles and on-call

  1. Q1/3 Mid-SEV1, the Incident Commander sees the Technical Lead is stuck on a database problem. What should the IC do?

    Answer & explanation

    Answer: C

    The IC is the single point of coordination and is explicitly not responsible for debugging; bringing in SMEs is how they unblock the technical work. An IC who starts debugging stops coordinating, which is exactly when parallel conflicting changes and missed communication creep in.

  2. Q2/3 Errors spike after a deploy. You roll back, impact stops, but nobody knows the actual bug yet. Which clock just stopped?

    Answer & explanation

    Answer: A

    Mitigation means user impact has stopped, even if the fix is not complete; the lesson says TTR may be longer than TTM and that is OK. Treating the rollback as resolution skips confirming no ongoing impact and the follow-up root-cause work.

  3. Q3/3 Which of these alerts should actually wake someone up (severity PAGE)?

    Answer & explanation

    Answer: D

    A page must be actionable and urgent with clear user impact: customers cannot complete purchases right now. High CPU may be fine if latency is OK, low disk can wait for business hours (NOTIFY), and a slow nightly job can wait until morning.

Chapter 3: Runbooks#

3.1 Runbook Structure#

Runbook structure

A runbook is a step-by-step guide for diagnosing and fixing an issue. It should be usable by someone at 3 AM who's never seen this issue before.

  1. Overview
    • What is this alert?
    • What is the user impact?
    • How urgent is it?
  2. Quick assessment (< 2 minutes)
    • Dashboard link
    • Key metrics to check
    • Is this real or false alarm?
  3. Common causes and fixes
    • Cause 1: [Description] — how to identify · how to fix
    • Cause 2: [Description] — how to identify · how to fix
    • Cause 3: [Description] — how to identify · how to fix
  4. Escalation
    • When to escalate
    • Who to escalate to
    • What information to provide
  5. Communication
    • Status page update template
    • Stakeholder notification list
  6. Post-incident
    • What to document
    • Follow-up actions

3.2 Example Runbook#

markdown153 lines
# Runbook: High Error Rate on Payment Service

## Overview

**Alert**: PaymentServiceErrorRateHigh
**Severity**: SEV1 (pages immediately)
**User Impact**: Customers cannot complete purchases
**Revenue Impact**: ~$10,000/hour during peak

## Quick Assessment (< 2 min)

1. **Open dashboard**: https://grafana.internal/d/payments
2. **Check error rate graph**: Is it actually elevated or a spike that resolved?
3. **Check scope**: All endpoints or specific one?
   ```
   Query: sum by (endpoint) (rate(payment_errors_total[5m]))
   ```
4. **Check timeline**: When did it start? Any correlation with deployments?

If error rate is < 1% and stable, this may be a false alarm. Monitor for 5 min.

## Common Causes and Fixes

### Cause 1: Recent Deployment

**How to identify**:
- Check deployment history: https://deploy.internal/payments
- Did error rate spike after a deployment?

**How to fix**:
```bash
# Rollback to previous version
kubectl rollout undo deployment/payment-service -n production

# Verify rollback
kubectl rollout status deployment/payment-service -n production
```

**Expected result**: Error rate should drop within 2-3 minutes.

---

### Cause 2: Database Connection Pool Exhausted

**How to identify**:
- Check DB connection metrics in dashboard
- Look for "connection refused" or "timeout" in logs
  ```bash
  kubectl logs -l app=payment-service -n production | grep -i "connection"
  ```

**How to fix**:
1. Scale up payment service (reduces load per pod):
   ```bash
   kubectl scale deployment/payment-service --replicas=10 -n production
   ```

2. If that doesn't help, check if slow queries are holding connections:
   ```sql
   SELECT pid, now() - pg_stat_activity.query_start AS duration, query
   FROM pg_stat_activity
   WHERE state = 'active' AND now() - pg_stat_activity.query_start > interval '30 seconds';
   ```

3. Kill long-running queries if safe:
   ```sql
   SELECT pg_terminate_backend(pid) FROM pg_stat_activity
   WHERE state = 'active'
     AND now() - query_start > interval '2 minutes'
     AND pid <> pg_backend_pid();
   ```

---

### Cause 3: Payment Provider Outage

**How to identify**:
- Check payment provider status page: https://status.stripe.com
- Check external API latency in dashboard
- Look for timeout errors in logs

**How to fix**:
1. If provider has fallback, enable it:
   ```bash
   # Enable Adyen as fallback
   kubectl set env deployment/payment-service PAYMENT_FALLBACK_ENABLED=true
   ```

2. If no fallback, consider enabling maintenance mode:
   ```bash
   # Enable maintenance mode for checkout
   kubectl set env deployment/api-gateway CHECKOUT_MAINTENANCE=true
   ```

3. Update status page with provider attribution.

---

### Cause 4: Traffic Spike Overwhelming System

**How to identify**:
- Check request rate: is it much higher than normal?
- Check if auto-scaling is running but not keeping up

**How to fix**:
1. Manually scale up:
   ```bash
   kubectl scale deployment/payment-service --replicas=20 -n production
   ```

2. Enable rate limiting if needed:
   ```bash
   kubectl set env deployment/api-gateway RATE_LIMIT_ENABLED=true
   ```

## Escalation

**Escalate if**:
- Issue not resolved within 15 minutes
- Root cause unclear
- Database expertise needed
- Customer communication needed

**Escalate to**:
- Primary: @payments-team-lead (Slack)
- Secondary: @platform-lead
- SEV1 escalation: Page secondary on-call

**Information to provide**:
- Current error rate and duration
- Steps already taken
- Suspected cause (if any)
- Links to relevant logs/dashboards

## Communication

**Status page update** (if > 10 min duration):
```
Title: Payment Processing Degraded
Body: Some customers may experience errors when completing purchases. 
Our team is actively investigating. We will provide updates every 15 minutes.
```

**Internal notification**:
- Slack: #incidents
- Include: Error rate, start time, impact, current status

## Post-Incident

- [ ] Document timeline in incident channel
- [ ] Create postmortem if SEV1/SEV2
- [ ] Update runbook if new cause found
- [ ] Create follow-up tickets for improvements

Chapter 4: Postmortems#

4.1 The Blameless Postmortem#

Blameless postmortem philosophy

The goal of a postmortem: Learn and improve, not punish.

Blameless means
  • People are not the root cause — Systems that allow human error are the cause
  • "Why did the system allow this to happen?" — Not "Why did this person make a mistake?"
  • Everyone operated with good intentions — Given what they knew at the time
  • Focus on systemic fixes — Not "person X should be more careful"
Why blameless?
If people fear blame If people feel safe
They hide mistakes They report issues early
Incidents go unreported They share near-misses
Near-misses aren't shared Root causes are found
Root causes stay hidden Systems get better
The same incidents happen again Incidents are prevented
Example
  • BLAME (no): "The engineer deployed without testing"
  • BLAMELESS (ok): "Our deployment process allowed untested code to reach production. We need automated test gates."

The fix is not "tell engineers to test more". The fix is "make it impossible to deploy without tests".

Your turn · checkpoint 4not answered

Estimate: where did the incident's minutes go?

A deploy goes out at 14:30. Errors start at 14:35, the alert fires at 14:42, on-call acknowledges at 14:45, the rollback starts at 14:55 and errors are back to normal at 15:00. What are the time to detect, time to engage and time to mitigate? Which part of the timeline would you attack first?

Think it through, or jot it down. Then compare.

One strong answer

  • Detect: 14:35 → 14:42 = 7 minutes. Engage: 14:42 → 14:45 = 3 minutes. Mitigate: 14:42 → 15:00 = 18 minutes from detection.
  • Users were affected for 25 minutes (14:35 → 15:00), and only the last 5 of those were the rollback itself.
  • So the biggest wins are catching the bad deploy sooner (canary analysis) and linking errors to deploys faster, not a faster rollback.

4.2 Postmortem Template#

markdown128 lines
# Postmortem: [Incident Title]

## Incident Summary

| Field | Value |
|-------|-------|
| **Date** | YYYY-MM-DD |
| **Duration** | X hours Y minutes |
| **Severity** | SEV1 / SEV2 / SEV3 |
| **Authors** | [Names] |
| **Status** | Draft / In Review / Complete |

### One-Line Summary
[One sentence describing what happened and the impact]

### Impact
- **User Impact**: [What users experienced]
- **Duration**: [How long they were impacted]
- **Scope**: [How many users affected]
- **Revenue Impact**: [$X estimated]
- **Data Impact**: [Any data loss/corruption]

---

## Timeline (All times in UTC)

| Time | Event |
|------|-------|
| 14:30 | Deployment of v2.3.1 to production |
| 14:35 | Error rate begins increasing |
| 14:42 | **DETECTED**: Alert fires for high error rate |
| 14:45 | **ENGAGED**: On-call acknowledges and begins investigation |
| 14:50 | Identified correlation with recent deployment |
| 14:55 | Rollback initiated |
| 15:00 | **MITIGATED**: Error rate back to normal |
| 15:15 | **RESOLVED**: Confirmed service fully restored |

**Key Metrics**:
- Time to Detect (TTD): 7 minutes (14:35 → 14:42)
- Time to Engage (TTE): 3 minutes (14:42 → 14:45)
- Time to Mitigate (TTM): 18 minutes from detection (14:42 → 15:00); rollback started at 13 minutes
- Total Incident Duration: 40 minutes (14:35 → 15:15)

---

## Root Cause Analysis

### What Happened
[Detailed technical explanation of what went wrong]

### Why It Happened (5 Whys)

1. **Why** did the service start returning errors?
   - Because database queries were timing out.

2. **Why** were queries timing out?
   - Because the new code introduced N+1 queries.

3. **Why** did the new code have N+1 queries?
   - Because the ORM change wasn't caught in code review.

4. **Why** wasn't it caught in code review?
   - Because we don't have automated detection for N+1 queries.

5. **Why** don't we have automated detection?
   - Because we haven't prioritized query analysis tooling.

**Root Cause**: Lack of automated N+1 query detection in our CI/CD pipeline.

### Contributing Factors
- Code review didn't catch the ORM change impact
- Load testing was skipped due to time pressure
- Staging environment doesn't have production-scale data

---

## What Went Well
- Alert fired quickly (7 min detection)
- On-call responded promptly
- Rollback procedure worked smoothly
- Communication to stakeholders was timely
- No data loss or corruption

## What Went Poorly
- N+1 query issue wasn't caught before production
- Took 5 minutes to link the errors to the deployment (the N+1 root cause was found later)
- There was no automated canary analysis, which would have caught this
- Staging data is not representative of production

---

## Action Items

| ID | Action | Owner | Priority | Due Date | Status |
|----|--------|-------|----------|----------|--------|
| 1 | Add N+1 query detection to CI | @alice | P1 | 2024-02-01 | TODO |
| 2 | Implement canary analysis for deployments | @bob | P1 | 2024-02-15 | TODO |
| 3 | Create production-like dataset for staging | @charlie | P2 | 2024-02-28 | TODO |
| 4 | Add ORM query patterns to code review checklist | @alice | P2 | 2024-02-01 | TODO |
| 5 | Document N+1 query patterns in eng wiki | @alice | P3 | 2024-02-07 | TODO |

---

## Lessons Learned

1. **Our deployment pipeline needs more automated checks**
   - We should catch performance regressions before production

2. **Rollback speed is critical**
   - 5-minute rollback time significantly reduced impact

3. **Staging != Production**
   - Data scale differences hide performance issues

---

## Appendix

### Relevant Logs
```
[Link to log search for incident timeframe]
```

### Dashboards
- [Link to metrics dashboard during incident]

### Related Incidents
- [Link to similar past incidents if any]
WorksheetWhat the 14:35 incident cost, phase by phase (steady loss at the runbook's peak rate is assumed)
Value
Revenue at risk at peak (from the runbook, assumed steady) ~$10,000/hour ≈ $167 a minute
Errors start → alert fires (time to detect) 7 min → ~$1,200
Alert → on-call engaged (time to engage) 3 min → ~$500
Engaged → rollback started (linking errors to the deploy) 10 min → ~$1,700
Rollback → errors back to normal 5 min → ~$800
Total user impact, 14:35 → 15:00 25 min → ~$4,200
Same incident with no alert, noticed from customer reports at 15:05 (assumed) 48 min → ~$8,000

Conclusion: 20 of the 25 minutes passed before the rollback even started, and the rollback itself took only 5 minutes (~$800). Good alerting already halved the cost; the action items go after the rest by catching the bad deploy before it reaches everyone (canary analysis, N+1 checks in CI).

4.3 The Five Whys Technique#

The five whys

A technique for finding root causes by asking "why" repeatedly.

Example 1: Website outage

Problem: Website went down

  1. Why did the website go down? → The web server crashed.
  2. Why did the web server crash? → It ran out of memory.
  3. Why did it run out of memory? → A memory leak accumulated over time.
  4. Why wasn't the memory leak caught? → We don't have memory profiling in our test suite.
  5. Why don't we have memory profiling? → We never prioritized performance testing tooling.

ROOT CAUSE: Lack of performance testing tooling FIX: Add memory profiling to CI/CD pipeline

Example 2: Data corruption

Problem: Customer orders showed wrong prices

  1. Why were prices wrong? → The price update script had a bug.
  2. Why did the buggy script run in production? → It wasn't tested with production-like data.
  3. Why wasn't it tested with production-like data? → Our staging database is much smaller.
  4. Why is staging database smaller? → We don't have a process to sync production data.
  5. Why don't we sync production data? → Privacy concerns haven't been addressed.

ROOT CAUSE: No process for anonymizing and syncing prod data FIX: Create data anonymization pipeline for staging

Tips for five whys
  1. Don't stop at human error — "Engineer made a mistake" is never the final answer
  2. Look for systemic issues — "Process allowed X to happen" is better than "person did X"
  3. It's OK if it's not exactly 5 — Sometimes it's 3, sometimes it's 7
  4. There may be multiple root causes — Branch the analysis if needed
  5. End when you reach something you can fix — And something that will prevent recurrence
Quick check3 questions · +5 XP each

Runbooks and postmortems

  1. Q1/3 The payment runbook's quick assessment shows the error rate jumped two minutes after a deployment. What is the first fix to apply?

    Answer & explanation

    Answer: B

    The runbook maps "error spike right after a deploy" to Cause 1, whose fix is a rollback, expected to clear errors within 2-3 minutes. Scaling or killing queries targets connection-pool exhaustion, a different cause; maintenance mode is a last resort when no fix or fallback exists.

  2. Q2/3 A Five Whys chain ends at "the engineer forgot to run the load test." What should the team do next?

    Answer & explanation

    Answer: D

    Human error is never the final answer: the question is why the system allowed it, ending at something fixable that prevents recurrence (e.g. an automated gate). "Be more careful" fixes nothing systemic, and the lesson notes the chain can be 3 or 7 steps, not strictly five.

  3. Q3/3 Postmortem timeline: deploy at 14:30, errors begin 14:35, alert fires 14:42, on-call acknowledges 14:45, rollback starts 14:55. What is the Time to Detect?

    Answer & explanation

    Answer: A

    TTD runs from when the issue actually started (errors at 14:35) to detection (alert at 14:42). 12 minutes wrongly starts at the deploy; 3 minutes is Time to Engage and 13 minutes is detection to rollback start.

Part II · Stage 2 of 4 · 8 min

Part II: Implementation#

Chapter 5: Incident Management System#

5.1 Incident Workflow Implementation#

pythonIncidentStatus · 388 lines
# incident/workflow.py

"""
Incident management workflow system.

Coordinates incident response from detection to resolution.
"""

from dataclasses import dataclass, field
from typing import List, Optional, Dict
from datetime import datetime, timezone
from enum import Enum
import uuid


class IncidentStatus(Enum):
    DETECTED = "detected"
    TRIAGING = "triaging"
    INVESTIGATING = "investigating"
    MITIGATING = "mitigating"
    MITIGATED = "mitigated"  # User impact stopped; the full fix may still be pending
    RESOLVED = "resolved"
    CLOSED = "closed"


class IncidentSeverity(Enum):
    SEV1 = 1  # Critical - all hands
    SEV2 = 2  # High - immediate attention
    SEV3 = 3  # Medium - business hours
    SEV4 = 4  # Low - normal queue


@dataclass
class IncidentRole:
    """A role assignment in an incident."""
    role: str  # "incident_commander", "technical_lead", "comms_lead"
    user_id: str
    assigned_at: datetime


@dataclass
class TimelineEvent:
    """An event in the incident timeline."""
    timestamp: datetime
    event_type: str  # "status_change", "action", "communication", "note"
    description: str
    user_id: str
    metadata: Dict = field(default_factory=dict)


@dataclass
class Incident:
    """An incident record."""
    id: str
    title: str
    description: str
    severity: IncidentSeverity
    status: IncidentStatus
    
    # Timing
    detected_at: datetime
    engaged_at: Optional[datetime] = None
    mitigated_at: Optional[datetime] = None
    resolved_at: Optional[datetime] = None
    
    # People
    roles: List[IncidentRole] = field(default_factory=list)
    
    # Timeline
    timeline: List[TimelineEvent] = field(default_factory=list)
    
    # Affected services
    affected_services: List[str] = field(default_factory=list)
    
    # Links
    slack_channel: Optional[str] = None
    video_call_link: Optional[str] = None
    postmortem_link: Optional[str] = None
    
    # Metadata
    tags: List[str] = field(default_factory=list)
    customer_impact: Optional[str] = None
    
    @property
    def time_to_detect(self) -> Optional[float]:
        """Minutes from actual issue start to detection."""
        # This would require knowing when issue actually started
        return None
    
    @property
    def time_to_engage(self) -> Optional[float]:
        """Minutes from detection to first responder."""
        if self.engaged_at:
            return (self.engaged_at - self.detected_at).total_seconds() / 60
        return None
    
    @property
    def time_to_mitigate(self) -> Optional[float]:
        """Minutes from detection to impact mitigation."""
        if self.mitigated_at:
            return (self.mitigated_at - self.detected_at).total_seconds() / 60
        return None
    
    @property
    def time_to_resolve(self) -> Optional[float]:
        """Minutes from detection to full resolution."""
        if self.resolved_at:
            return (self.resolved_at - self.detected_at).total_seconds() / 60
        return None


def _fmt_minutes(value: Optional[float]) -> str:
    """Format a duration in minutes; a milestone that never happened shows as n/a."""
    return "n/a" if value is None else f"{value:.0f} minutes"


class IncidentManager:
    """
    Manages incident lifecycle and coordination.
    """
    
    def __init__(
        self,
        slack_client,
        pagerduty_client,
        status_page_client,
        database
    ):
        self.slack = slack_client
        self.pagerduty = pagerduty_client
        self.status_page = status_page_client
        self.db = database
    
    async def create_incident(
        self,
        title: str,
        description: str,
        severity: IncidentSeverity,
        affected_services: List[str],
        triggered_by: str
    ) -> Incident:
        """
        Create a new incident and initiate response.
        """
        incident = Incident(
            id=str(uuid.uuid4()),
            title=title,
            description=description,
            severity=severity,
            status=IncidentStatus.DETECTED,
            detected_at=datetime.now(timezone.utc),
            affected_services=affected_services
        )
        
        # Add creation event
        incident.timeline.append(TimelineEvent(
            timestamp=datetime.now(timezone.utc),
            event_type="status_change",
            description=f"Incident created: {title}",
            user_id=triggered_by
        ))
        
        # Create incident channel
        channel = await self._create_incident_channel(incident)
        incident.slack_channel = channel
        
        # Page on-call if SEV1 or SEV2
        if severity in [IncidentSeverity.SEV1, IncidentSeverity.SEV2]:
            await self._page_on_call(incident)
        
        # Update status page if SEV1
        if severity == IncidentSeverity.SEV1:
            await self._create_status_page_incident(incident)
        
        # Save to database
        await self.db.save_incident(incident)
        
        return incident
    
    async def assign_role(
        self,
        incident_id: str,
        role: str,
        user_id: str,
        assigned_by: str
    ):
        """Assign a role to a user."""
        incident = await self.db.get_incident(incident_id)
        
        # Remove existing role assignment if any
        incident.roles = [r for r in incident.roles if r.role != role]
        
        # Add new assignment
        incident.roles.append(IncidentRole(
            role=role,
            user_id=user_id,
            assigned_at=datetime.now(timezone.utc)
        ))
        
        incident.timeline.append(TimelineEvent(
            timestamp=datetime.now(timezone.utc),
            event_type="action",
            description=f"Assigned {role} to {user_id}",
            user_id=assigned_by
        ))
        
        await self.db.save_incident(incident)
        await self._notify_channel(
            incident.slack_channel,
            f"🎯 {user_id} is now {role}"
        )
    
    async def update_status(
        self,
        incident_id: str,
        new_status: IncidentStatus,
        message: str,
        user_id: str
    ):
        """Update incident status."""
        incident = await self.db.get_incident(incident_id)
        old_status = incident.status
        incident.status = new_status
        
        # Update timing fields
        now = datetime.now(timezone.utc)
        if new_status == IncidentStatus.INVESTIGATING and not incident.engaged_at:
            incident.engaged_at = now
        elif new_status == IncidentStatus.MITIGATED and not incident.mitigated_at:
            # TTM ends when impact stops, not when mitigation work starts
            incident.mitigated_at = now
        elif new_status == IncidentStatus.RESOLVED and not incident.resolved_at:
            incident.resolved_at = now
            if not incident.mitigated_at:
                incident.mitigated_at = now  # Resolving also ends the impact
        
        # Add timeline event
        incident.timeline.append(TimelineEvent(
            timestamp=now,
            event_type="status_change",
            description=f"Status: {old_status.value} → {new_status.value}. {message}",
            user_id=user_id
        ))
        
        await self.db.save_incident(incident)
        
        # Notify channel
        status_emoji = {
            IncidentStatus.INVESTIGATING: "🔍",
            IncidentStatus.MITIGATING: "🔧",
            IncidentStatus.MITIGATED: "🩹",
            IncidentStatus.RESOLVED: "✅",
        }.get(new_status, "📋")
        
        await self._notify_channel(
            incident.slack_channel,
            f"{status_emoji} Status update: {new_status.value}\n> {message}"
        )
        
        # Update status page
        if incident.severity == IncidentSeverity.SEV1:
            await self._update_status_page(incident, message)
    
    async def add_note(
        self,
        incident_id: str,
        note: str,
        user_id: str
    ):
        """Add a note to the incident timeline."""
        incident = await self.db.get_incident(incident_id)
        
        incident.timeline.append(TimelineEvent(
            timestamp=datetime.now(timezone.utc),
            event_type="note",
            description=note,
            user_id=user_id
        ))
        
        await self.db.save_incident(incident)
        await self._notify_channel(
            incident.slack_channel,
            f"📝 Note from {user_id}: {note}"
        )
    
    async def resolve_incident(
        self,
        incident_id: str,
        resolution_summary: str,
        user_id: str
    ):
        """Resolve the incident."""
        await self.update_status(
            incident_id,
            IncidentStatus.RESOLVED,
            resolution_summary,
            user_id
        )
        
        incident = await self.db.get_incident(incident_id)
        
        # Generate summary
        summary = f"""
🎉 Incident Resolved

**Duration**: {_fmt_minutes(incident.time_to_resolve)}
**Time to Engage**: {_fmt_minutes(incident.time_to_engage)}
**Time to Mitigate**: {_fmt_minutes(incident.time_to_mitigate)}

**Resolution**: {resolution_summary}

Next steps:
1. Schedule postmortem (within 48 hours)
2. Complete any follow-up actions
3. Update documentation if needed
"""
        
        await self._notify_channel(incident.slack_channel, summary)
        
        # Close status page incident
        if incident.severity == IncidentSeverity.SEV1:
            await self._close_status_page_incident(incident)
    
    async def generate_postmortem_draft(
        self,
        incident_id: str
    ) -> str:
        """Generate a postmortem template from incident data."""
        incident = await self.db.get_incident(incident_id)
        
        # Format timeline
        timeline_table = "| Time | Event |\n|------|-------|\n"
        for event in incident.timeline:
            time_str = event.timestamp.strftime("%H:%M UTC")
            timeline_table += f"| {time_str} | {event.description} |\n"
        
        template = f"""
# Postmortem: {incident.title}

## Incident Summary

| Field | Value |
|-------|-------|
| **Date** | {incident.detected_at.strftime("%Y-%m-%d")} |
| **Duration** | {_fmt_minutes(incident.time_to_resolve)} |
| **Severity** | SEV{incident.severity.value} |
| **Status** | Draft |

### One-Line Summary
[TODO: One sentence describing what happened and the impact]

### Impact
- **User Impact**: [TODO]
- **Duration**: {_fmt_minutes(incident.time_to_resolve)}
- **Scope**: [TODO]

---

## Timeline (All times in UTC)

{timeline_table}

**Key Metrics**:
- Time to Engage (TTE): {_fmt_minutes(incident.time_to_engage)}
- Time to Mitigate (TTM): {_fmt_minutes(incident.time_to_mitigate)}
- Total Incident Duration: {_fmt_minutes(incident.time_to_resolve)}

---

## Root Cause Analysis

### What Happened
[TODO: Detailed technical explanation]

### Why It Happened (5 Whys)
[TODO: Apply 5 whys technique]

---

## Action Items

| ID | Action | Owner | Priority | Due Date | Status |
|----|--------|-------|----------|----------|--------|
| 1 | [TODO] | [TODO] | P1 | [TODO] | TODO |

---
"""
        return template

Chapter 6: Communication During Incidents#

6.1 Internal Communication#

Internal communication during incidents
Incident channel structure

Create a dedicated Slack channel: #inc-YYYY-MM-DD-short-description

Example: #inc-2024-01-15-payment-errors

Channel topic (set immediately)

"SEV1: Payment errors affecting checkout IC: @alice | Tech: @bob | Comms: @charlie Status: Investigating | Started: 14:42 UTC"

Update cadence
Severity Cadence
SEV1 Every 15 minutes minimum
SEV2 Every 30 minutes minimum
SEV3 Every hour or at major milestones
Update format
  • [14:50] Status: Investigating
    • Identified correlation with deployment at 14:30
    • Error rate: 5% (down from 8%)
    • Working on: Rollback decision
    • Next update: 15:05
  • [14:57] Status: Mitigating
    • Rollback initiated at 14:55
    • Error rate: 2% (decreasing)
    • ETA to normal: 5 minutes
    • Next update: 15:12 or when resolved
  • [15:15] Status: Resolved
    • Rollback complete; error rate back to 0.5% (normal) since 15:00
    • Duration: 40 minutes (users affected for 25)
    • Postmortem to be scheduled

These updates follow the same incident as the postmortem timeline in §4.2.

6.2 External Communication#

External communication (status page)
Principles
  1. Be honest — Don't hide issues. Customers know anyway. Transparency builds trust.
  2. Be timely — First update within 10 minutes of detection. Updates every 15-30 minutes during incident.
  3. Be clear — Plain language, not technical jargon. Focus on impact to users.
  4. Be accountable — Don't blame third parties. Own the customer experience.
Status page update templates
Stage Template
INVESTIGATING "We are investigating reports of [issue]. Some customers may experience [impact]. We will provide updates every 15 minutes."
IDENTIFIED "We have identified the cause of [issue] and are working on a fix. [Impact] is ongoing. We expect to resolve this within [timeframe]."
MONITORING "We have implemented a fix and are monitoring the results. [Impact] should be resolving. We will confirm resolution shortly."
RESOLVED "This incident has been resolved. [Brief explanation]. We apologize for any inconvenience and are taking steps to prevent this from happening again."
What NOT to say
Don't say Why
"A third-party provider caused this outage" Customers don't care, you chose the provider
"An engineer deployed a bug" Internal details, sounds like blame
"We're not sure what's happening" Be honest but not helpless
Technical jargon: "Database replication lag" Customers don't understand or care
Quick check3 questions · +5 XP each

Incident tooling and communication

  1. Q1/3 In the IncidentManager.create_incident flow, what happens when an incident is created as SEV2?

    Answer & explanation

    Answer: C

    Every incident gets a dedicated channel and SEV1/SEV2 page on-call, but only SEV1 automatically creates a status page incident. Assuming every paged incident goes public would put internal-only degradations on the status page.

  2. Q2/3 It is a SEV1 and your next update is due, but you have learned nothing new since the last one. What do you post?

    Answer & explanation

    Answer: A

    SEV1 updates go out at least every 15 minutes even with no progress; silence causes more panic than an honest "still investigating." Guessing a root cause risks misleading stakeholders, and going quiet is exactly the "skipping communication" mistake.

  3. Q3/3 Your checkout outage was caused by your payment provider. Which status page message follows the lesson's principles?

    Answer & explanation

    Answer: B

    Good external messages are plain, impact-focused, timely and accountable: you chose the provider, so you own the customer experience. Blaming a third party, using technical jargon or sounding helpless are all on the "what not to say" list.

Part III · Stage 3 of 4 · 3 min

Part III: Real-World Application#

Chapter 7: Case Studies#

7.1 How Google Does Incident Response#

Google's incident response

From the SRE book and public talks:

Structure
  • Incident Commander (IC) — Single point of decision-making
  • Operations Lead (Ops) — Works directly on the problem
  • Communications Lead (Comms) — Handles stakeholder updates
  • Planning Lead (for long incidents) — Manages logistics, handoffs
Key practices
  1. Clear command structure
    • IC makes final decisions
    • IC doesn't debug - they coordinate
    • IC can delegate decisions explicitly
    • Only one IC at a time
  2. War rooms
    • Virtual or physical gathering point
    • All responders in one channel
    • Reduces communication lag
    • Video call for complex incidents
  3. Role handoffs
    • Incidents can last hours or days
    • Explicit handoff process
    • "I'm handing IC to [name]"
    • Handoff briefing: current state, next steps
    • Acknowledgment required
  4. Postmortem culture
    • Postmortem for all significant incidents
    • Blameless by policy
    • Action items tracked to completion
    • Postmortems shared widely for learning
  5. Error budgets affect response
    • If error budget exhausted, stricter process
    • Feature freeze until reliability improved
    • Incident response tied to SLO

Lesson: The structure and roles matter more than individual heroics.

7.2 How Stripe Does Incident Response#

Stripe's approach

Context: Payments = zero tolerance for errors

Illustrative: these are common practices for high-stakes systems, not a published description of Stripe's internal process.

Key practices
  1. On-call excellence
    • Extensive on-call training
    • Shadow shifts before going live
    • Regular game days (practice incidents)
    • On-call is a respected role
  2. Runbooks for everything
    • Every alert has a runbook
    • Runbooks tested regularly
    • If no runbook, create one during incident
    • Runbooks reviewed in postmortems
  3. Automated response
    • Automatic rollback on error spike
    • Automatic scaling on load
    • Automatic circuit breaking
    • Reduce need for human intervention
  4. Rapid postmortems
    • Postmortem within 48 hours
    • Short format for quick turnaround
    • Focus on action items
    • Follow-up tracked in system
  5. Learning from near-misses
    • Report issues even if no impact
    • Analyze near-misses like incidents
    • Find systemic issues before they cause outages
    • "Near miss → fix it before it's a miss"

Lesson: For high-stakes systems, invest heavily in prevention and preparation.

Chapter 8: Common Mistakes#

Incident response anti-patterns
Mistake 1: Too many cooks
Wrong Right
Everyone jumps in to help Clear roles assigned
Multiple people making changes IC coordinates all changes
No coordination One person makes changes at a time
Changes conflict with each other "I'm changing X" announced before acting
Mistake 2: Skipping communication
Wrong Right
Heads down fixing the problem First status update within 10 minutes
Stakeholders don't know what's happening Regular updates even if no progress
Customers learn about outage from Twitter Status page updated immediately
Leadership surprised Leadership briefed for SEV1
Mistake 3: Blame culture
Wrong Right
"Who deployed this?" Focus on what, not who
"How could you not test this?" "How did our process allow this?"
Public shaming in postmortem Systemic fixes, not personal criticism
People hide mistakes Safe to report issues
Mistake 4: No postmortem
Wrong Right
Incident resolved, move on Postmortem within 48 hours
No analysis of what happened Root cause analysis
Same incident happens again Action items assigned and tracked
No improvement Learnings shared widely
Mistake 5: Alert fatigue
Wrong Right
50 pages per week < 5 pages per week (target)
Most alerts are false positives Every alert is actionable
On-call ignores alerts False positives are fixed
Real issues missed On-call trusts alerts
Quick check3 questions · +5 XP each

Real-world practice and anti-patterns

  1. Q1/3 During a SEV1, five engineers each try a different fix at the same time and the error rate keeps swinging. What change helps most?

    Answer & explanation

    Answer: D

    "Too many cooks" makes changes conflict and hides which one helped; the fix is clear roles with the IC coordinating every change. Waiting for the postmortem abandons mitigation, which comes first while users are still affected.

  2. Q2/3 A team gets about 50 pages a week, most of them false positives. What is the real danger?

    Answer & explanation

    Answer: C

    Alert fatigue erodes trust in the pager: when most pages are noise, the real one gets ignored. The remedy is fewer, actionable alerts and fixing false positives, not a cheaper pager.

  3. Q3/3 Following the lesson's Stripe example, why analyze a near-miss that had no customer impact?

    Answer & explanation

    Answer: A

    "Near miss, fix it before it's a miss": near-misses reveal the same systemic gaps as outages, at zero cost to users. Using near-misses to assign responsibility would make people stop reporting them, undoing the blameless culture.

Part IV · Stage 4 of 4 · 6 min

Part IV: Interview Preparation#

Chapter 9: Interview Tips#

9.1 Incident Management Discussion Framework#

Discussing incidents in interviews

When asked "How would you handle an incident?":

  1. Structure is key — "First, I'd establish clear roles:
    • Incident Commander for coordination
    • Technical Lead for debugging
    • Comms Lead for stakeholders

    This prevents chaos and ensures coordination."

  2. Mitigation over root cause — "My first priority is mitigating user impact. Can we rollback? Can we failover? Root cause investigation comes after we've stopped the bleeding."
  3. Communication — "I'd set up an incident channel, update stakeholders every 15 minutes, and update the status page within 10 minutes. Silence is worse than 'we're investigating.'"
  4. Learning — "After resolution, I'd run a blameless postmortem. The goal is to find systemic issues and prevent recurrence, not assign blame. We'd track action items to completion."
  5. Prevention — "The best incident is one that doesn't happen. I'd invest in monitoring, alerting, runbooks, and regular game days to prepare the team."
❯ Say this

9.2 Key Phrases#

Incident management key phrases
On response

"My first question is 'what's the user impact?' That determines severity and urgency. A backend error with no user impact is different from checkout being down."

On roles

"I believe in clear incident command. One person coordinates, others execute. Without this, you get five people all trying to fix the problem differently."

On communication

"I'd update stakeholders every 15 minutes, even if the update is 'still investigating.' Silence causes more panic than honest updates about uncertain situations."

On postmortems

"Postmortems must be blameless. If we blame individuals, people hide mistakes. The question is 'how did our system allow this?' not 'who made the error?'"

On prevention

"Every incident should produce action items that prevent recurrence. If we don't learn, we're just firefighting forever. Track action items like any other work."

On alert design

"Every page should be actionable and important. If an alert fires and the response is 'wait and see,' it shouldn't be a page. Alert fatigue causes missed real issues."

Chapter 10: Practice Problems#

Practice · problem 1

Problem 1: Payment Outage#

Scenario: You're on-call. At 2 AM, you're paged: "Payment success rate dropped from 99% to 85%."

Questions:

  1. What's your first 5 minutes?
  2. How do you communicate?
  3. What's your mitigation strategy?
Click for approach
  1. First 5 minutes:

    • Acknowledge the page
    • Check dashboard for scope and timeline
    • Is it all payments or specific type?
    • When did it start? Correlate with deployments
    • Quick assessment: real issue or false alarm?
  2. Communication:

    • Create incident channel: #inc-2024-01-15-payment-degradation
    • Declare SEV1 (payments are critical)
    • Page secondary on-call for support
    • Update status page: "Investigating payment processing issues"
    • Notify leadership via Slack/text
  3. Mitigation:

    • If recent deployment: consider rollback
    • If external provider: check their status, enable fallback
    • If load-related: scale up, enable rate limiting
    • Priority: restore payments, investigate later

Practice · problem 2

Problem 2: Postmortem Scenario#

Scenario: An engineer deployed code that caused a 30-minute outage. Leadership wants to know "who did this."

Questions:

  1. How do you handle the leadership question?
  2. What should the postmortem focus on?
  3. What action items might emerge?
Click for approach
  1. Handling leadership:

    • Redirect from "who" to "how"
    • "The individual is less important than understanding how our process allowed this to happen"
    • Share that blameless culture leads to better outcomes
    • Offer to present postmortem findings
  2. Postmortem focus:

    • Why did the code have a bug? (Testing gap?)
    • Why wasn't it caught in code review? (Reviewer didn't know to look?)
    • Why wasn't it caught in staging? (Data difference?)
    • Why wasn't rollback faster? (Process gap?)
  3. Action items:

    • Add automated test for this scenario
    • Update code review checklist
    • Improve staging data to match production
    • Reduce rollback time with automation
    • Share learnings with other teams

Chapter 11: Sample Interview Dialogue#

Transcript
Interviewer

"Walk me through how you'd handle a major production incident."

You

"Let me walk through the complete lifecycle.

Detection and Triage:"

When the alert fires
  1. Acknowledge within 5 minutes
  2. Quick assessment: Is this real? What's the scope?
  3. Declare severity based on user impact
  4. For SEV1/2: Create incident channel, page backup

"For a SEV1 like 'checkout is down', I'd immediately escalate to a war room model:"

War room setup
  • Slack channel: #inc-2024-01-15-checkout-down
  • Video call for complex coordination
  • Assign roles:
    • Myself as IC (or delegate if I'm debugging)
    • Senior engineer as Technical Lead
    • Manager or senior as Comms Lead
Transcript
Interviewer

"How do you decide what to do first?"

You

"Mitigation over investigation. The priority is stopping user impact.

My decision tree:"

DiagramMitigation decision tree
%% title: Mitigation decision tree
flowchart TD
  Q1{"1. Was there a<br/>recent deployment?"} -->|"YES"| A1["Can we rollback safely?"]:::ok
  Q1 -.->|"NO"| Q2{"2. Is a dependency down?"}
  Q2 -->|"YES"| A2["Can we failover or<br/>degrade gracefully?"]:::ok
  Q2 -.->|"NO"| Q3{"3. Are we overloaded?"}
  Q3 -->|"YES"| A3["Can we scale up<br/>or rate limit?"]:::ok

I'm looking for the fastest way to restore service, even if it's not the 'correct' fix. We investigate root cause after users are happy.

Transcript
Interviewer

"What about communication during the incident?"

You

"Communication is as important as the fix itself.

My communication plan:"

My communication plan

Status page

  • First update within 10 minutes
  • Template: "We are investigating issues with [X]"
  • Update every 15 minutes even if no change
  • Include ETA when known

Internal

  • Update incident channel every 10-15 minutes
  • Format: Status | What we know | What we're doing | Next update
  • Escalate to leadership for SEV1

Stakeholders

  • Customer support team briefed
  • Sales team notified if major customers affected
  • Executive summary for leadership
Transcript
Interviewer

"After it's resolved, then what?"

You

"The incident isn't really over until we've learned from it.

Post-incident:"

Post-incident
  1. Within 48 hours: Blameless postmortem
    • Timeline reconstruction
    • 5 Whys root cause analysis
    • What went well / what went poorly
    • Action items assigned with owners and dates
  2. Action items tracked like any other work
    • In sprint planning
    • Regular check-ins
    • Actually get done (not just documented)
  3. Share learnings
    • Post summary in engineering channel
    • Update runbooks if needed
    • Consider if training needed
Transcript
Interviewer

"Good comprehensive answer. One last question: how do you prevent incidents?"

You

"Prevention is the best incident response.

Prevention strategies:"

Prevention strategies
  1. Observability: Can't fix what you can't see
    • Metrics, logs, traces all correlated
    • Dashboards for key services
  2. Alerting: Right alerts that are actionable
    • Every alert has a runbook
    • Regular review of alert quality
  3. Testing: Catch issues before production
    • Load testing for capacity
    • Chaos engineering for resilience
    • Canary deployments for safety
  4. Game days: Practice incident response
    • Simulated incidents quarterly
    • Test runbooks and communication
  5. Culture: Safe to report issues
    • Blameless postmortems
    • Celebrate near-miss reports

Summary#

Day 5 key takeaways
Incident lifecycle

Detection → Triage → Response → Mitigation → Resolution → Learning

Key roles
  • Incident Commander: Coordinates, doesn't debug
  • Technical Lead: Diagnoses and fixes
  • Communications Lead: Updates stakeholders
Priorities
  • Mitigation first, investigation second
  • Communication is not optional
  • Restore service, then find root cause
On-call
  • Sustainable rotations (≥8 people)
  • Actionable alerts only
  • Runbooks for every alert
  • Proper handoffs between shifts
Postmortems
  • Blameless (systems fail, not people)
  • Within 48 hours while memory fresh
  • 5 Whys for root cause
  • Action items tracked to completion
Communication
  • First update within 10 minutes
  • Regular updates even if no progress
  • Plain language, not technical jargon
  • Own the customer experience
Key insight

The best incident response is built on preparation: good alerts, tested runbooks, practiced teams. Heroics are a sign of system failure.

Further Reading#

Books:

  • Book

    "Site Reliability Engineering" by Google (Free online)

  • Book

    "The Phoenix Project" by Gene Kim

  • Book

    "Incident Management for Operations" by Rob Schnepp

Resources:

  • Docs

    PagerDuty Incident Response Guide (free)

  • Read

    Atlassian Incident Management Handbook

  • Book

    Google SRE Book - Chapter on Incident Response

Tools:

  • Read

    PagerDuty: Alerting and on-call management

  • Read

    Incident.io: Incident management workflows

  • Read

    Statuspage: External communication

  • Read

    Jeli: Incident analysis and learning

Week 10 Complete!#

Week 10 complete

Production Readiness and Operational Excellence

Day Topic Purpose
Day 1 SLIs, SLOs, SLAs Define what "healthy" means
Day 2 Observability See whether you're healthy
Day 3 Deployment Strategies Maintain health through change
Day 4 Capacity Planning Ensure health under load
Day 5 Incident Management Respond when health fails
The production engineer's toolkit
  • SLOs tell you what healthy means
  • Observability tells you if you're healthy
  • Deployment strategies keep you healthy through change
  • Capacity planning keeps you healthy under load
  • Incident management restores health when it fails

Together, these skills let you operate reliable systems that serve users well, even at scale, even under stress.

Next: Week 10 Capstone — Bringing together everything from Weeks 1-10 in a comprehensive system design interview simulation.

You've built the complete toolkit of a senior production engineer. The capstone will test your ability to apply all of it together.

this lesson in shorts · 3

play them all →

One idea from this lesson in about a minute each, made for your phone.

End of Day 05 · Incident Management
Finish Day 5Stages clear as you read them (0/4 so far). Skipping ahead doesn't count: marking complete unlocks after ~7 more min of reading.

Go deeper · reading trail

all reading →

Real write-ups from the teams that built these systems. Each opens on the publisher's site in a new tab.

GoogleDocs · ~11 min

Managing Incidents

Andrew Stribblehill · 2016
What
The SRE book chapter on running an incident.
Key idea
Separate roles (incident commander, operations, communications, planning), keep a live incident document and hand off command explicitly.
Why here
The incident response fundamentals of this lesson, with an example of an incident managed badly and then well.
taught here: Incident response roles
AtlassianDocs · ~20 min

The Atlassian Incident Management Handbook

What
Atlassian's public handbook for how its teams detect, respond to and learn from incidents.
Key idea
It defines what counts as an incident, sets values for each stage (know before customers do, escalate early), describes the incident manager role and ends in postmortems that assign actions.
Why here
A complete process to borrow for this lesson's on-call, runbook and postmortem sections.
taught here: Postmortems
CloudflarePostmortem · ~23 min

Details of the Cloudflare outage on July 2, 2019

John Graham-Cumming · 2019
What
Cloudflare's detailed postmortem of a global outage.
Key idea
A new WAF rule contained a regular expression that backtracked badly and exhausted CPUs on every HTTP-serving core worldwide; the fix list covers testing, rollout and regex engines.
Why here
A model postmortem for this lesson: timeline, root cause, why safeguards failed and concrete follow-ups.
taught here: Blameless postmortems

New lessons by email

New lessons, side quests and case files as they ship, at most once a week. No spam, unsubscribe anytime.

Discussion · …

Public: everyone reading this lesson sees comments. Be kind and keep it on the material.

Sign in to ask a question or answer one. Reading stays open to everyone.
loading the discussion…