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.
Before a new service goes live and starts taking on-call pages, what would you want to see in place? Walk through what a production-readiness review should check.
Sample Answer
A production-readiness review should verify four things before a service starts taking pages: it fails safely (degrades or rolls back instead of cascading), it's observable enough that on-call can diagnose without guessing, on-call actually knows how to respond to it, and someone specific owns it. Structure the review around those four, not a flat checklist, so gaps are obvious by category rather than buried in a long list.
What the review checks, by category
| Category | What to verify | Why it's a gate, not a nice-to-have |
|---|---|---|
| Failure containment | Circuit breakers or timeouts on every downstream call; load-testing evidence at expected peak plus a safety margin; tested rollback path | Without these, a dependency hiccup or a launch-day traffic spike becomes an on-call incident that a healthy service wouldn't have had |
| Observability | Dashboards for the service's key health signals; alerts tied to those signals with sane thresholds (not just "CPU high"); logs/traces sufficient to diagnose the top 3 failure modes without SSH-ing into a box | On-call can't respond to what they can't see; this is the difference between a 10-minute diagnosis and a 2-hour one |
| Runbook readiness | At least one runbook per alert that can actually fire, covering symptom, diagnosis steps, and remediation; runbook has been read (ideally walked through) by the people who'll be paged | An alert with no runbook just wakes someone up with no next step |
| Ownership and escalation | Named on-call rotation for the service, not "whoever's around"; a documented escalation path if the primary can't resolve it; the service is actually in the paging tool's routing, not just assumed to be | Ambiguous ownership is invisible until the first incident, when it costs the most |
Process for running the review
- The owning team self-certifies against the checklist first, providing evidence (load-test results, a link to the rollback runbook, a screenshot of the dashboard) rather than a checked box with no backing.
- A reviewer outside the owning team (SRE or a peer team) spot-checks the evidence, focusing on the failure-containment and observability rows, since those are the ones teams under launch pressure are most likely to overstate.
- Run one live-fire test before go-live: trigger the most likely failure mode in staging (or a controlled prod canary) and confirm the alert fires, the runbook's diagnosis steps actually find the cause, and the rollback works. A checklist that's never been exercised is a hypothesis, not a verified readiness state.
- Sign-off is explicit and time-bound, not a one-time gate that's forgotten: re-review triggers on major architecture changes, not just at initial launch.
flowchart TD
A[Owning team self-certifies checklist] --> B[Provide evidence: load tests, runbook links, dashboards]
B --> C[Outside reviewer spot-checks evidence]
C --> D{Gaps found?}
D -->|Yes| E[Team remediates gap]
E --> C
D -->|No| F[Live-fire test in staging or canary]
F --> G{Alert fires, runbook works, rollback succeeds?}
G -->|No| E
G -->|Yes| H[Sign-off: service takes pages]
Worked example
A new recommendations service is going live. Self-certification claims load testing was done "at expected traffic." The outside reviewer asks for the actual load-test report and finds it tested at the current expected peak (500 req/s) with no margin, while the service also sits behind a feature flag that product plans to ramp to three times that within a month. That's a real gap: the review isn't asking for perfection, but it should require either testing at the higher number now or an explicit, documented plan (with an owner and date) to re-test before the ramp, rather than letting "tested at expected traffic" silently mean "tested at today's traffic." The live-fire test then finds the circuit breaker on the downstream recommendation-model call has no timeout configured, so a slow model response would hang the request instead of failing fast; that's flagged as a blocking issue, not a follow-up ticket, because it directly causes cascading failure under exactly the load condition the service is meant to handle.
Trade-offs and pitfalls
The live-fire test step is the one teams most often skip under launch deadline pressure, and it's also the one that catches the gaps self-certification checklists miss (an alert that's configured but never actually fires, a runbook step that references a dashboard that doesn't exist); treat it as non-negotiable for anything customer-facing, and reserve a lighter self-certification-only path for low-risk internal services. A common wrong turn is treating the checklist as complete once every box is checked, without weighting which gaps are load-bearing; a missing rollback plan for a payments-adjacent service is not the same severity as a missing dashboard for an internal admin tool, and the review should say so explicitly rather than gating everything equally.
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.
How would you keep an organization's runbooks accurate and useful over time instead of letting them rot? Talk through ownership and how you'd catch a runbook that's gone stale before someone relies on it during an incident.
Sample Answer
Runbooks rot because nothing forces them to change when the system they describe changes. Keeping them accurate means giving every runbook a named owner, tying updates to the events that actually invalidate a runbook (a relevant code or infra change, or an incident where it was used), and having a lightweight, recurring check that catches staleness before an incident does, rather than relying on someone remembering to update it.
Ownership
Every runbook has one named primary owner, the team or person who owns the service it covers, recorded in the runbook itself, not a separate spreadsheet that gets forgotten. Ownership isn't honorary: the owner is the one who signs off that the runbook is still accurate at each review point, and the one paged if a stale runbook causes a bad outcome during an incident.
What triggers a review, not just a calendar date
Calendar-only review cadences ("review every quarter") catch some staleness but miss the more common case: a runbook goes stale the day the system changes underneath it, not on a schedule. Two triggers matter more than the calendar:
- Change-linked: any deploy that touches the commands, infra, or thresholds a runbook references should require a runbook update as part of that same change, enforced by a checklist item on the pull request, not a follow-up ticket that competes with the next sprint.
- Incident-linked: every time a runbook is actually used during an incident, the post-incident review includes a specific question, did the runbook match reality, and any gap becomes a tracked follow-up before the incident is closed.
Lifecycle stages
| Stage | Meaning | Who moves it | Trigger |
|---|---|---|---|
| Active | Verified accurate, safe to follow blind | Owner | Passed its last review or was just used successfully in an incident |
| Needs review | A linked change or incident flagged it as possibly stale | Owner, auto-flagged | Change-linked or incident-linked trigger fires |
| Deprecated | Still readable but no longer the source of truth | Owner | Replacement runbook exists, or the failure mode it covers no longer applies |
| Archived | Removed from the on-call surface entirely | Owner | Deprecated for a defined grace period with no further reliance |
Catching a stale runbook before someone relies on it
A stale runbook is genuinely dangerous exactly because it looks trustworthy right up until the moment it's wrong. The cheapest catch is a light automated check, does every command in the runbook reference a tool, dashboard, or endpoint that still exists, run periodically and flagging anything broken for owner review. The more valuable catch is a periodic game-day: pick a runbook, have someone unfamiliar with the system try to follow it against a staging environment, and see where it breaks. Anything that trips someone up in a drill would have tripped up the on-call engineer at 3am.
Worked example: what enforcement actually looks like
A pull request changes the retry/backoff config for a service. The PR template includes a checkbox, "does this change any runbook referenced by this service's on-call docs?" Because the change alters a value a runbook's remediation step depends on, the author checks yes and links the runbook update in the same PR. Two months later, that runbook gets used during an incident; the post-incident review confirms the values matched, so the runbook stays Active with its last-reviewed date updated, no separate ticket needed because the change-linked trigger already did the work.
Trade-offs and pitfalls
Tying every infra change to a mandatory runbook update adds friction to routine PRs, so the check needs to be scoped narrowly (does this specific change affect a specific runbook) rather than a blanket "update all docs" gate that people learn to click through without reading. The most common failure mode is having a lifecycle model on paper but no one actually enforcing the Needs review to Active transition, so runbooks accumulate silently in Needs review and the label stops meaning anything; the fix is making that queue visible (a dashboard, not a buried label) and reviewing it in the same recurring meeting as on-call handoffs.
Design the guardrails for a system that lets on-call engineers trigger automated runbook actions directly from an alert. How do you prevent a misfire, or a compromised trigger, from causing a bigger outage than the one it was meant to fix?
Sample Answer
Direct answer
Guardrails come from three layers working together: classify every automatable action by risk, reversibility and blast radius, so low-risk actions can run unattended while destructive ones require signed, multi-party approval; rate-limit and circuit-break execution so a misfiring trigger can't repeat itself into a bigger outage; and make every execution auditable and traceable to a specific signed, version-pinned runbook so a compromised trigger's blast radius stays bounded even if it does fire.
Structured elaboration
Threat model
- Misfire: a legitimate alert misclassifies severity or triggers the wrong action, such as restarting the wrong service.
- Compromised automation pipeline: an attacker forges or replays an alert to trigger a destructive action.
- Insider abuse: someone with legitimate access triggers an action outside its intended use.
Each needs a different control. Misfire needs validation and rate limits. Compromise needs signing and short-lived credentials. Insider abuse needs approval gates and an audit log that can't be edited after the fact.
Guardrail decision flow
flowchart TD
A[Alert triggers automated action] --> B{Reversible and low blast radius?}
B -->|Yes, low risk| C{Under rate-limit threshold?}
C -->|Yes| D[Execute in sandboxed, least-privilege runner]
C -->|No| E[Circuit-break: block further auto-actions]
B -->|No, high risk or destructive| F[Require signed approval from two operators]
F --> G{Approved within TTL?}
G -->|Yes| D
G -->|No| H[Escalate to human on-call, no auto-execution]
D --> I[Write signed, tamper-evident audit entry]
Core controls
- Risk classification: every automatable action is tagged low, medium, or high at authoring time, reviewed like code, based on reversibility and blast radius.
- Rate limiting and circuit breaking: cap executions per action per time window, and auto-disable an action after repeated failures instead of letting it keep firing.
- Signing and provenance: only signed, version-pinned runbook releases execute in production; the executor verifies the signature first, so a compromised trigger can request an action but can't smuggle in unreviewed logic.
- Least privilege and short-lived credentials: the executor pulls scoped, time-limited credentials per execution rather than holding standing broad access.
- Immutable audit trail: every execution, who or what triggered it, the parameters, and the outcome, is written to an append-only log kept separate from the systems it can act on, so it survives a compromise of the executor itself.
Worked example
| Action | Reversibility | Blast radius | Risk tier | Guardrail |
|---|---|---|---|---|
| Restart a single stateless pod | Fully reversible | One instance | Low | Auto-execute, rate-limited to one per 5 minutes per pod |
| Drop and rebuild a search index | Not reversible without a full rebuild | Whole service | High | Requires two signed operator approvals within a 10-minute TTL |
Consider an attacker who can forge an alert payload. Against the pod-restart action, they're bounded by the rate limit and the action's inherently small blast radius. Against the index-drop action, they're blocked at the approval gate no matter how convincing the forged alert looks, because approval requires a human signature that an alert payload can't fake.
Trade-offs and pitfalls
- Classifying everything as needing approval defeats the point of automation, which is unattended response to the common case. Keep destructive steps as a separate, explicitly gated action rather than bundling them with routine remediation, so most actions land in the low-risk tier by design.
- More approval gates reduce blast radius but increase mean time to remediate; mitigate by keeping the low-risk tier wide and reserving gates for the genuinely destructive minority.
- Signing the runbook but not validating its parameters leaves a gap: a signed, but freely parameterizable, action like "restart <service>" can still be misused if the parameter itself isn't checked against an allowlist.
Where's the line between an operational runbook and a security incident-response playbook, and how do you keep a responder from accidentally leaking something sensitive, like pasting a live credential, into a runbook they're editing during an incident?
Sample Answer
The line is intent, not tooling: a runbook assumes the failure isn't malicious and defaults to fast, reversible operational actions, while a security playbook assumes it might be and defaults to preserving evidence and escalating. The handoff between them has to be a written, specific trigger list, not a judgment call made under pressure.
Runbook versus security playbook
| Dimension | Operational runbook | Security playbook |
|---|---|---|
| Default assumption | Failure is a bug, capacity issue, or bad deploy | Failure may involve an actor with intent |
| Default first action | Restart, scale, roll back, mitigate fast | Isolate and preserve, don't destroy evidence |
| Who leads | On-call engineer or SRE | Security on-call; engineer supports under their direction |
| Speed pressure | Restore service as soon as possible | Get it right; evidence and scope matter more than speed |
Handoff triggers (explicit, not a judgment call)
- A known indicator-of-compromise match (signature, known-bad IP, tampered binary).
- Automated remediation failing repeatedly while a new suspicious artifact appears.
- Any sign of lateral movement or a cross-service authentication anomaly.
- Any alert crossing a predefined confidence-plus-impact threshold agreed with security in advance.
Handoff flow
flowchart TD
A[Runbook step in progress] --> B{Indicator of compromise?}
B -->|No| C[Continue runbook as operational issue]
B -->|Yes| D[Isolate and preserve evidence, non-destructive]
D --> E[Open incident ticket with artifacts]
E --> F[Notify security on-call, SLA clock starts]
F --> G[Security triages within SLA]
G --> H[Security leads containment and investigation]
H --> I[SRE executes infra changes under security direction]
Keeping a live credential out of the runbook in the first place
The mechanism isn't "tell people not to paste secrets," it's removing the need to. Runbooks reference secret IDs resolved from a vault at execution time, the same underlying mechanism used to control access to any sensitive step, so there's rarely a reason to type a raw value into the document at all. For the cases where a responder is genuinely debugging and tempted to paste a live value for reference, a secret-scanning check on the runbook-editing tool (pattern and entropy-based) that blocks the save and asks for a redacted reference instead is a cheaper and more reliable control than relying on discipline during an incident.
Trade-offs and pitfalls
Treating every operational failure as a potential security incident slows down the vast majority of pages that are genuinely just a bad deploy; keep the trigger list narrow and specific rather than "when in doubt, escalate." The more dangerous direction is the opposite: treating every alert as operational until proven otherwise is how evidence gets destroyed by a well-meaning restart before anyone realizes it mattered, so the trigger list has to be actively taught, not just written down somewhere. Keeping runbooks and playbooks in separate systems owned by separate teams is how the handoff criteria silently drift out of sync with what each team actually expects; version-control both in one place with cross-references and joint review.
Unlock Full Question Bank
Get access to all 42 On-Call Practices and Runbook Design interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.