On-Call Practices and Runbook Design Questions
Running a sustainable on-call function: rotation design, production-readiness handoffs, and authoring runbooks that let responders act quickly. Covers runbook automation, on-call culture, escalation-ready documentation, and readiness reviews before a service takes production traffic. The operational-preparedness discipline that makes incidents survivable.
Some runbook steps involve sensitive actions, like production database admin commands or rotating credentials. How do you control who can run those steps and keep it auditable, without slowing a responder down during a real P1?
Sample Answer
Don't gate sensitive steps behind standing credentials a responder already holds. Gate them behind short-lived, narrowly scoped credentials issued by the runbook orchestrator at the moment of use, with a pre-authorized fast path for the highest severities so speed during a real incident doesn't require quietly bypassing the audit trail.
Comparing access models
| Model | Speed during a P1 | Auditability | Blast radius if leaked |
|---|---|---|---|
| Shared static credential in a vault everyone can read | Fast | Poor, can't tell who actually used it | High, valid indefinitely until manually rotated |
| Manual per-use approval (ticket plus human sign-off) | Slow, adds minutes exactly when they're scarce | Good | Low, but the delay is itself a cost during a P1 |
| Just-in-time ephemeral credential (vault-issued, scoped, short TTL, auto-revoked) | Fast for pre-authorized P1 paths | Excellent, tied to identity, ticket, and TTL window | Low, expires on its own even if forgotten |
Worked example: sizing the credential TTL
If the median observed time to complete a given remediation step across past incidents is 12 minutes, a 15-minute TTL leaves almost no margin:
Margin=15−12=3 mina responder who hits a snag is interrupted 3 minutes short of done, exactly when stopping is most disruptive. A TTL of roughly 20 minutes, the median plus a working buffer rather than an open-ended grant, gives room to finish without leaving a long-lived credential outstanding. A 4-hour TTL "to be safe" instead means a credential compromised from a responder's terminal during that window stays valid for the rest of the shift; that's the trade being made for the extra convenience.
Keeping it auditable without slowing the responder down
- Runbooks reference secret IDs, never raw values, so the document itself is safe to read even if it leaks.
- The orchestrator executes the sensitive step server-side where practical, so the responder never sees the decrypted secret at all, only the outcome.
- Every credential issuance logs identity, ticket or incident ID, scope, and TTL to an immutable log, correlated automatically rather than reconstructed after the fact.
- The highest severities get pre-authorized issuance, no waiting on a human approver, precisely because the TTL and logging, not a manual gate, are what keep it auditable.
Trade-offs and pitfalls
A break-glass path needs more audit rigor than the normal path, not less; pair any emergency bypass with mandatory post-incident review and automatic rotation of whatever it touched. Auto-approval for the highest severities removes a human gate exactly during the highest-risk window (a real incident, adrenaline, and possibly an actor exploiting the chaos), so the TTL and logging have to carry that weight instead. Orchestrator-executed remediation is safer for the responder but adds its own risk surface; the automation itself now needs the same change-review rigor as production code, not less because "it's just a script."
Walk me through how you'd run a postmortem after a Sev1 incident: what data you'd gather, how you separate contributing factors from the root cause, and how you turn it into action items that actually get done.
Sample Answer
Direct answer
Run the postmortem in three phases: reconstruct a fact-based timeline from logs, metrics, and deploy history before the meeting even starts; use a structured technique during the meeting, like the "5 whys" or a fishbone breakdown, to separate genuine contributing factors from the actual root cause; and convert findings into specific, owned, time-boxed action items that get tracked to closure rather than filed and forgotten.
Structured elaboration
Data to gather before the meeting
- A precise timeline: when the alert fired, was acknowledged, mitigated, and resolved, with timestamps and who acted at each step.
- Dashboards showing the SLO breach before, during, and after.
- Logs and traces from the affected window, correlated across every service involved, not just the one that alerted first, since the alerting service is often a symptom rather than the cause.
- Deploy and config change history around the incident window, including commit references, feature flags, and infra changes.
- The runbook steps actually executed and their outcomes.
Separating contributing factors from root cause
| Technique | What it's for |
|---|---|
| Timeline correlation | Narrows the causal window before anyone starts theorizing |
| 5 whys | Drills from the symptom to an actionable, systemic cause; stop at the point where fixing it would have prevented the outage |
| Fishbone (Ishikawa) | Categorizes contributors, people, process, code, infra, monitoring, so several independent factors aren't collapsed into one "root cause" |
| Forensic log correlation | For a non-obvious failure spanning multiple components, joins logs and traces by request ID or timestamp across services instead of trusting any single service's self-report |
A factor is a contributing factor if removing it alone would not have prevented the outage. It's the root cause only if removing it would have. Multiple genuine root causes are possible and should be named as such rather than forced into one.
Turning findings into action items that get done
Each item is specific, owned by exactly one person, carries a due date and an explicit acceptance criterion, such as "add an alert that fires when X, verified by injecting a synthetic breach and confirming it pages." Items are prioritized by risk reduced versus effort and tagged by urgency the same way incidents are, so remediation work competes visibly against other roadmap work. They're tracked in the same system as regular engineering work, with a scheduled follow-up check that closure actually happened and actually worked.
Worked example
- 14:02 UTC: a config deploy ships a change to the connection-pool size for checkout-service.
- 14:07 UTC: a checkout-service latency alert fires.
- 14:09 UTC: on-call acknowledges and begins triage on checkout-service logs, the service that alerted.
- 14:18 UTC: correlating logs across checkout-service and its downstream payments-service shows connection-pool exhaustion actually originated in payments-service; the earlier deploy had reduced its pool size, and checkout-service was just the first caller to see timeouts.
- 14:22 UTC: on-call rolls back the payments-service config; latency recovers.
- Root cause: the connection-pool config change on payments-service, since removing it would have prevented the outage. Contributing factor: no alert existed on payments-service's own pool saturation, only on downstream symptoms, which meant triage started on the wrong service before cross-service log correlation found the real source.
- Action items: add a connection-pool saturation alert directly on payments-service, owned by the payments team, verified by injecting a synthetic pool-exhaustion test and confirming it pages before the downstream symptom would; and require connection-pool config changes to go through the same review gate as code changes, owned by the platform team.
Trade-offs and pitfalls
- Stopping at the first plausible "why," usually the service that alerted, instead of correlating across the actual dependency chain is how a downstream root cause gets misattributed to whichever service merely surfaced the symptom first.
- Writing action items as vague intentions, like "improve monitoring," instead of specific, verifiable changes with an owner and an acceptance test, is the single biggest reason action items don't get done.
- A longer, more thorough timeline reconstruction produces a more accurate root cause but delays the meeting; worth it for a top-severity incident, disproportionate for a lower-severity one.
Design a severity rubric, say P0 through P3, for a SaaS product. What determines the level, what SLA applies at each, and who has to be paged?
Sample Answer
Direct answer
Base the rubric on customer-facing impact and business consequence, not internal technical severity: P0 is a full outage or a safety or data-loss risk with immediate paging and an aggressive SLA, scaling down through partial-impact and degraded-but-functional states to P3, a backlog item with no paging at all. Each level pairs a concrete definition with a response SLA, a resolution SLA, and exactly who gets paged, so classification is a lookup an on-call engineer can make under pressure, not a judgment call.
Structured elaboration
| Severity | Impact | Response SLA | Resolution SLA | Who's paged |
|---|---|---|---|---|
| P0 | Full outage, data loss or corruption, or safety or legal risk, affecting all or most customers | Page immediately, acknowledge within 5 minutes | Continuous work until mitigated, target under 4 hours | On-call engineer, service owner, incident commander, security or legal if data exposure |
| P1 | Major feature broken for many customers, or one high-value customer severely impacted; SLA-covered functionality degraded | Page, acknowledge within 15 minutes | Target under 24 hours, mitigation expected sooner | On-call engineer, team tech lead, customer success for affected accounts |
| P2 | Partial degradation, a subset of users, intermittent errors, core flows still work | Notify without paging, acknowledge within 1 hour during business hours | Target under 3 business days | Feature owner; on-call optional |
| P3 | Cosmetic issue, edge case, no measurable customer impact | Acknowledge within 1 business day | Scheduled into normal backlog | No paging; filed and triaged by product and engineering |
What determines the level
- Scope: how many customers or what fraction of traffic is affected.
- Reversibility of harm: data being lost or corrupted pushes toward P0 regardless of how few customers are affected, versus a fully recoverable error.
- Whether a workaround exists for the customer.
- Contractual exposure: whether this breaches an SLA the company is financially on the hook for.
Reclassifying as more information arrives
Declare an initial severity fast, from the first available signal, and treat it as provisional. Many incidents start looking like P1 and get upgraded to P0 once data loss is confirmed, or start as P0, a total outage, and downgrade to P1 once a workaround is found. Reclassification in either direction should be cheap and require no approval, because holding onto an inaccurate severity either under-pages a real emergency or burns unnecessary on-call attention.
Worked example
A payment-processing API returns errors for all merchants for several minutes before an automatic circuit breaker reroutes traffic to a backup provider, after which errors drop back to baseline. Applying the table: the initial signal, all merchants affected and revenue-blocking, classifies this as P0 and pages the on-call engineer, the service owner, and the incident commander immediately. Once the reroute confirms the impact is contained and no data was lost, the incident is reclassified to P1, SLA-covered functionality degraded with a workaround in place via the backup provider, for the remainder of the response. That reclassification changes the resolution SLA from continuous work under 4 hours to a target under 24 hours, but it doesn't stand down the already-paged responders mid-incident.
Trade-offs and pitfalls
- Defining severity by an internal technical signal, like an error-rate threshold, instead of customer impact, treats a high error rate on a low-traffic internal endpoint the same as the same error rate on checkout, which it isn't.
- Too many severity levels creates ambiguity at classification time under pressure; four tiers is usually enough resolution to route paging and SLAs correctly without forcing a judgment call between two levels that don't functionally differ.
- Making reclassification require a meeting or approval means on-call will just leave the severity wrong, which quietly corrupts incident metrics later.
A runbook's automated remediation step ran and it caused a partial outage instead of fixing anything. How would you investigate what went wrong, and what would you change to prevent it from happening again?
Sample Answer
When an automated remediation makes things worse, the first move is to stop trusting the automation, not to debug it live: disable the trigger (feature flag or scheduler pause) so it can't fire again while you investigate, then treat the automation's own actions as the incident's primary evidence trail.
Investigation approach
- Pull the automation's own audit log first. What did it decide to do, on what input, at what timestamp? Most remediation frameworks log the triggering condition and the action taken; if this one doesn't, that's itself a finding.
- Reconstruct the precondition it evaluated against. Was the health check it used stale (cached metrics, delayed scrape) or narrower than reality (checked one replica's health, not cluster quorum)?
- Check for concurrency. Did two instances of the same remediation run at once, or did it run while a human was mid-deploy? Interleaved writes to the same resource are a common cause of "fix that broke things."
- Diff the assumed environment against the actual one. Runbooks and remediation scripts encode assumptions (resource names, API versions, cluster topology) that drift silently; check whether the automation was written against a topology that's since changed.
Framework for the fix
- Add a pre-check gate: the remediation must verify the system is in the state it assumes (quorum present, no in-flight deploy, dependency healthy) before acting, and abort loudly if not.
- Make the action idempotent and reversible: re-running it, or running it against a system already in the target state, should be a no-op, and every destructive step needs a paired rollback.
- Bound the blast radius: act on one node/instance first (canary), verify success, then proceed, rather than acting cluster-wide in one shot.
- Add a concurrency guard: a lock or lease so two triggers of the same remediation can't run simultaneously.
- Gate high-impact actions behind a second signal: require the automation to see the problem confirmed by two independent signals (e.g., an alert plus a direct health check) before taking a destructive action, not just one noisy metric.
Worked example
Suppose the remediation is: "if a node reports high memory for 3 consecutive scrapes, cordon and drain it." The postmortem finds the metrics scraper had a 90-second collection lag during a load spike, so by the time the automation cordoned the third node it was actually reading data that was already 4.5 minutes stale (three 90-second-lagged scrapes), and it drained three nodes in the same 2-minute window because the memory spike was cluster-wide, not node-specific. Losing three nodes at once dropped the cluster below quorum for its replicated service, which is the partial outage.
The fix that follows directly from that trace: (a) the pre-check should compare current live memory, not the lagged scrape, before acting; (b) the automation should check how many nodes it has already drained in the current window and refuse to exceed a cap (e.g., no more than one node per 10 minutes) until a human confirms; (c) it should check that the remaining fleet still satisfies quorum before draining another node.
Trade-offs and pitfalls
Adding pre-checks and rate caps makes the remediation slower to react, which is the right trade for anything that can cause an outage of its own; reserve fully unthrottled auto-remediation for actions that are cheap to reverse (like restarting a single stateless pod) and keep caps and human gates on anything that removes capacity or touches shared state. A common wrong turn is to respond to this incident by simply disabling the automation permanently and reverting to manual remediation: that trades a rare automation bug for a much larger population of slower, inconsistent manual responses. The senior move is to narrow what the automation is trusted to do unsupervised, not to abandon automation.
How would you actually validate that your runbooks work before you need them in a real incident? Describe a program for testing them under realistic conditions.
Sample Answer
Direct answer
Validating runbooks before a real incident needs three ingredients: a way to safely exercise them, using sandboxes for non-destructive steps and canary execution for destructive ones; measurable acceptance criteria for what "verified" actually means; and a cadence that scales from cheap, frequent tabletop walkthroughs up to expensive, rare full game days. Treat validation as a graded ladder of increasing realism and cost, not a single all-or-nothing chaos exercise.
Structured elaboration
Ladder of validation
| Tier | What happens | Frequency | Blast radius |
|---|---|---|---|
| Tabletop read-through | Team reads the runbook aloud, checks it still matches current architecture | Monthly per critical runbook | None, discussion only |
| Sandboxed dry-run | Non-destructive or dry-run steps run against a synthetic or staging copy | Per runbook change, CI-gated | Isolated sandbox |
| Canary execution | The real, potentially destructive step runs against a single instance or shard in production | Quarterly for the highest-severity runbooks | One instance or shard |
| Full game day | The real trigger condition is simulated and the whole runbook runs end to end with the actual on-call rotation | Quarterly cross-team, and after major architecture changes | Scoped production traffic, with a kill switch |
Acceptance criteria for "verified"
- Every command in the runbook executed successfully against the environment matching its tier.
- Recovery met the documented RTO (recovery time objective: the maximum acceptable downtime) for that exercise.
- The person executing it was not the runbook's original author, which catches "only the author can actually run this" runbooks.
- No manual step was needed beyond what's written, which catches missing steps.
- The runbook's last-verified metadata is updated only after all of the above pass, tied to the specific commit that was tested.
Sandboxing and canary mechanics for destructive steps
- A dry-run flag on any script validates and logs without mutating anything; most cloud SDKs and infrastructure-as-code tools support this natively.
- Ephemeral, synthetic-data environments handle full destructive rehearsals safely, isolated by namespace or project and feature-flagged away from real customer traffic.
- Steps that can only be meaningfully tested in production, like a real failover, get a canary first: a single shard or instance, with an automated rollback path and a pre-agreed abort condition.
Error-budget gate before running in production
Before a production game day, confirm enough error budget remains to absorb the intended, and any accidental, impact. For a monthly SLO of 99.9 percent over a 30-day window, the allowed downtime is:
error budget=(1−SLO)×window minutes
(1−0.999)×43,200=0.001×43,200=43.2 minutes
If the remaining budget is close to that 43.2-minute figure, postpone the exercise rather than spend the safety margin on a drill.
Worked example
A cache-cluster failover runbook is canary-tested against a single shard. The failover command executes without manual intervention, recovery meets the documented RTO target, and the engineer running the drill is not the runbook's original author. All four acceptance criteria above pass, so the runbook's last-verified metadata is updated to the exact commit hash that was tested, and the result feeds into the quarterly decision of whether this runbook is due for a full game day next.
Trade-offs and pitfalls
- Relying only on tabletop reads because full game days are expensive means staleness in the actual commands never gets caught until a real incident does it for you.
- Letting the runbook's author be the only person who can successfully execute it means you've tested the author's tribal knowledge, not the documentation; a different operator running the drill is what actually validates the doc.
- Full production game days build the highest confidence but carry real risk and spend real error budget; the ladder exists so most validation stays cheap, and only the highest-severity runbooks earn a full game day.
Unlock Full Question Bank
Get access to all On-Call Practices and Runbook Design interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.