Ten examples for severity levels, comms channels, and a first-15-minutes checklist - the foundation every Expo SDK 57 on-call rotation needs before a crash spike, bad OTA, or store delisting. Pair with Observability Basics for signal taxonomy and Rollback Runbook for OTA containment.
Your team should already ship with release identity on every crash and log - see Sentry for React Native. These examples assume EAS Update channels and Sentry Release Health are wired for production.
Tooling: These examples target Expo SDK 57 (expo ~57.0.4), React Native 0.86.0, and React 19.2.3.
Web-style P1/P2 labels fail on mobile because store adoption, OTA propagation, and offline users stretch blast radius. Use impact-based severity:
// docs/incident-severity.ts - copy into your runbook repoexport type IncidentSeverity = "SEV1" | "SEV2" | "SEV3" | "SEV4";export type SeverityCriteria = { sev: IncidentSeverity; userImpact: string; revenuePath: boolean; example: string;};export const MOBILE_SEVERITY_MATRIX: SeverityCriteria[] = [ { sev: "SEV1", userImpact: "App unusable for majority OR removed from store OR data breach", revenuePath: true, example: "Play suspension; auth down for all users on live build", }, { sev: "SEV2", userImpact: "Critical path broken for >25% of active users", revenuePath: true, example: "Checkout crash on iOS 2.4.0 phased release", }, { sev: "SEV3", userImpact: "Regression with workaround; partial rollout or single platform", revenuePath: false, example: "Settings tab crash on Android preview channel", }, { sev: "SEV4", userImpact: "Internal-only, policy warning, or sub-threshold metric drift", revenuePath: false, example: "Sentry noise on dev profile; App Store metadata deadline", },];
SEV1 pages exec, legal, and comms - not just engineering
SEV2 is the default production crash spike with payment or auth involvement
SEV3 can wait for business hours if a kill switch exists
Re-evaluate severity every 30 minutes - OTA propagation can escalate SEV3 → SEV2 quickly
Mobile incidents span engineering, support, executives, and app store status. Separate channels by audience:
## Comms map| Channel | Audience | Content rules ||---------|----------|---------------|| `#incident-YYYYMMDD` | Engineering + IC | Technical facts, commands run, hypotheses || `#incident-comms` | Support + PM + Comms | Approved customer-facing language only || PagerDuty / Opsgenie | On-call | Alert → acknowledge → join incident channel || Status page | Customers | No root cause until confirmed; no blame || Exec email | C-suite | Business impact, ETA range, what we are doing now |
# Internal (engineering) - OKSuspect OTA group abc123 published 14:02 UTC. Crash-free dropped 99.4% → 96.1%.Running eas channel:view production. IC: @jane.# External (status page) - OKWe are investigating reports of ShopApp closing unexpectedly on some devices.Next update in 30 minutes or sooner.# External - NEVERCaused by @bob's deploy. Rolling back now.
Engineering channel is noisy - that's fine; comms channel is curated
Support macros must match status page wording - mismatched messages create ticket storms
Mobile spikes often look like backend outages until you segment by client version.
// Log at session start - support and incidents depend on thisimport * as Application from "expo-application";import * as Updates from "expo-updates";export function getIncidentCorrelationTags() { return { nativeRelease: `${Application.nativeApplicationVersion}+${Application.nativeBuildVersion}`, otaUpdateId: Updates.updateId ?? "embedded", channel: Updates.channel ?? "none", runtimeVersion: Updates.runtimeVersion ?? "unknown", };}
Structured updates reduce duplicate work and prevent IC from re-answering the same question.
## Status template (post every 15–30 min)**SEV:** SEV2**IC:** @jane**Impact:** Checkout crash on iOS build 240012 (~18% phased users)**Containment:** Phased release paused; flag `newCheckout` off**Next:** Bisect OTA vs native - see Crash Spike Triage**ETA:** Next update 15:45 UTC
Pin the latest status message in the incident channel
Link to Sentry issue cluster URL - not screenshots of stack traces
@channel only for severity changes or containment confirmation - not every hypothesis
The on-call mobile engineer or release manager with authority to pause store rollouts and approve OTA rollback. IC does not need to be the person who wrote the buggy code - they need decision authority and calm under alert noise.
Is a crash spike always SEV2?
No. A spike on an optional tab affecting <1% of sessions with a kill switch available may be SEV3. Payment or auth regression on the live production build is SEV2 or SEV1 depending on scope. Use the severity matrix in Example 1, not alert volume alone.
What if we cannot tell OTA from native?
Filter Sentry by dist (OTA update id) and release (native version+build). If crashes span all OTA ids on one native build, suspect native. If isolated to one update id, suspect JS bundle. See Crash Spike Triage.