opsinjs
HealthColour, status and attention

Alarm fatigue

Escalation is budgeted rather than judged screen by screen. This page sets the ceiling, names who owns it, and says what an interface loses by overspending it.

What this means

Alarm fatigue is the best-documented failure mode in clinical technology. In hospitals, monitors generate enough alarms that competent, trained and motivated staff stop responding to them, silence them pre-emptively, or tune them out entirely. Each alarm is individually reasonable and the aggregate is noise, and people have been harmed by alarms that fired correctly into a room where nobody was listening any more. The evidence for alarm fatigue as a documented problem, and the limits of its transfer to a consumer app, are set out under "Why (evidence)" below.

Consumer health apps reproduce the pattern at lower stakes, until the stakes are not low. A ring closes, a streak breaks, a weekly report is ready, a device needs charging, a reading is a little high, a subscription is expiring, and each of these arrives with the same visual weight and the same buzz. The reader learns from the repetition that this app's notifications do not require action, and that is the expectation they bring to the alert that does. How many low-value alerts that learning takes is something we have not measured.

Each individual decision to escalate is defensible on its own terms, and fatigue is a property of the aggregate rather than of any one decision. No single screen's review can detect it, which is why opsinjs governs escalation with a budget rather than with a per-screen judgement.

The rule

Escalation is a finite, explicitly budgeted resource. Every surface that escalates must be spent against a stated budget, and the budget is enforced at the screen and at the session rather than at the component.

Escalation budgets by scope

The budget sets five ceilings across four scopes, two of them at the screen.

ScopeCeilingFailure mode it preventsBasis
One screenAt most one urgent surfaceTwo urgent surfaces on one screen ask the reader to decide which of them to act on first, and a lay reader has no basis on which to rank two urgent claims.Follows from the triage argument; chosen rather than derived.
One screenAt most two attention surfacesPast two, the reader's scan is divided across the set, and we expect each surface to be read less closely than it would have been alone.A judgement about scanning rather than a measurement.
One sessionAt most one interruptive modal that the reader did not initiateAn interruption the reader did not ask for stops the task they opened the app to do, and it is the most expensive item in this budget.A judgement about goodwill.
One dayAt most one non-clinical push notificationA push arrives at a moment the reader did not choose, so a low-value one spends the attention that the next clinical one will need.
Any surfaceurgent is reserved for clinical urgencyA commercial or product problem rendered as urgent is indistinguishable from a clinical one at the moment the reader sees it.

Two of the five ceilings carry no entry under Basis. The daily limit on non-clinical push is administered by Notifications and off-screen alerts, which owns scheduling and grouping, and the reservation of urgent for clinical urgency is fixed by the status vocabulary on Clinical status semantics rather than chosen here.

The escalation ladder

The ladder has five rungs in a normative order, and a surface moves up a rung only when the rung below it has been used and has proved insufficient, never because a rung looks more important.

RungSurfaceAddressed toBlocks the readerCondition for using it
1. AmbientA StatusPill on the value itselfNobody in particular; it is a property of the valueNoThe default rung, available wherever a status is shown
2. In-placeA CareCard in the flow of the screen, next to the value it is about, carrying a named actionThe reader of that value, at the point it appearsNoRung 1 is in use and the value needs a named action travelling with it
3. Screen-levelAn AlertBanner at the top of the screenThe reader of the screenNoRung 2 is in use and has proved insufficient
4. InterruptiveA modal or a sheet the reader must dismissThe reader, at the moment they arriveYes, until it is dismissedThe message is time-critical and cannot wait for the reader to reach it
5. Off-screenA push notificationThe reader while the app is closedIt interrupts outside the app rather than blocking inside itRung 4 is in use and has proved insufficient, and the message is never a first attempt; it is the most expensive rung on the ladder, and its delivery is governed by Notifications and off-screen alerts

Rules that close the routes around the budget

Every ceiling above can hold while escalation is still overspent, and three further rules cover those cases: one fact carried on several rungs at once, a surface that is never withdrawn, and a surface re-raised on a timer.

  • No parallel escalation. The same fact does not get a pill and a card and a banner at once. One fact occupies the highest rung it justifies, and the surfaces below that rung are suppressed.
  • De-escalation and its announcement. When a value returns to steady, the surface that escalated it is removed, and the reader is told once that it has gone.
  • The re-raise condition. Repeating an unchanged attention banner on successive opens does not increase the chance of action, and it reduces the response rate to later banners. A surface re-raises on a change of state rather than on a timer.

Why (evidence)

Applying it

Do

Suppress the lower rungs when a higher one fires. If an AlertBanner is already telling the reader their blood pressure needs checking, the tile below shows a watch pill rather than a second banner.

Don’t

Let every component decide its own urgency independently. No component-level review sees the aggregate of the screen, so a set of individually reasonable decisions produces an unreadable screen that passes every one of those reviews, which is why enforcement sits at the screen and at the session.

Do

Track alert volume per user as a product metric with a target ceiling, the way you track error rate. A stated ceiling is what makes the aggregate reviewable after release, where a screen-level review cannot reach.

Don’t

Measure alerts by click-through alone. Click-through on a newly introduced alert measures its novelty as much as its value, and it does not show what happens to the response rate as the same alert repeats unchanged.

Do

Tell the reader when something has resolved: "Your blood pressure readings are back in your usual range." The sentence states both that the surface has gone and why it has gone, and the de-escalation rule above requires it to be said once rather than repeated.

Don’t

Remove the banner without saying anything. A reader who cannot tell whether the value returned to steady or the app dropped the surface has no reason to treat the next banner as reliable.

Do

Give engagement, retention and commercial messages their own quiet channel that is visually and structurally separate from the clinical one, so that a reader can tell which channel a message arrived on before reading it.

Don’t

Borrow the clinical channel for a streak reminder because it gets noticed. The attention it borrows is the attention the next clinical alert on that channel will need, and the reader has no way to tell the two apart in advance.

Sound and haptics carry their own budget, and it is smaller than the visual one because a sound or a vibration cannot be skimmed past and reaches whoever is nearby as well as the reader. See Sound and haptics and Motion in health UI.

Components that implement this

AlertBanner is specified to expose the budget rather than hide it: a screen that mounts a second urgent banner should fail loudly in development instead of rendering two. That behaviour is a specification and not shipped code. The component itself ships and does warn in development about several things, including a missing heading level and an attention or urgent banner with no action, but nothing counts banners across a screen, because a component cannot see its siblings. The budget is enforced by review today, and the specified behaviour is what the component will be held to when something can enforce it.

What this does not cover

Four topics fall outside this page. Three of them are covered elsewhere in the corpus, and continuous clinical monitoring is outside opsinjs altogether.

Excluded topicWhy it is out of scopeWhere it is covered
Which readings deserve to escalate at allThe decision is a clinical threshold, and opsinjs does not set clinical thresholdsClinical status semantics
Notification scheduling, quiet hours and OS-level groupingDelivery mechanics are governed separately from the ceilings this page setsNotifications and off-screen alerts
The interaction pattern for staged escalationThis page fixes the ceilings and the ladder, while the sequence, the wording and the components belong to a patternAlert escalation
Clinical monitoring systemsContinuous monitoring with alarms is a regulated domain with its own standards, and it requires an analysis this page does not attempt

Updates to this page

Last read through against the system on 2026-09-02. Due for review every 6 months; expiry is reported by pnpm run check:freshness.

On this page