Security

Paging Without a Big Ops Team: On-Call for Small Companies

Antonio Evans10 min read

A small kitchen table at night: a phone face-up, screen glowing with a paging alert, next to a half-finished mug of tea and a laptop showing a status dashboard with one red tile.
Key points

Key points

  1. 1Page a human only for symptoms users feel (error rate, latency, failed logins), and route every page to a named primary and secondary with a short escalation timeout.
  2. 2A written escalation policy with explicit timeouts stops alerts from stalling because one person hesitated to wake someone else.
  3. 3Weekly, daily or split rotations each fit a different team size, and the right choice depends on how often the page actually fires.
  4. 4Review pages weekly and delete or demote any alert that woke a person without needing a human decision.

Start from the symptom, not the graph

On-call at a small company usually fails for one reason: too many pages, or pages that wake the wrong person at the wrong time. Google's SRE guidance is blunt about this. Alerting should be driven by what users experience, and a page should mean "a human must act now," while everything else belongs in a ticket or a dashboard (Monitoring Distributed Systems). The same argument is made more directly in Google's write-up on symptom-based alerting: users do not care why something is broken, only that it is broken (Why Focus on Symptoms, Not Causes?).

That gives you a decision rule you can apply in an afternoon. For each existing alert, ask: would a user notice this within the next few minutes? If yes, it can page. If no, it goes to a channel, a ticket or a dashboard. A CPU graph crossing a threshold is a cause. A checkout page returning errors for real sessions is a symptom.

Build the short list of paging signals first. For most small companies it is four to six:

SignalPages a human whenRead fromTypical human action
HTTP 5xx rateOver threshold for a sustained window on the main appLoad balancer or APM error rateRoll back, fail over, scale
p95 latency on critical pathsAbove target for several minutesAPM or edge timingFind the slow dependency
Failed login or auth errorsSpike relative to baselineAuth service logsCheck provider status, key expiry
Payment or order failuresAny sustained failure on the checkout pathPayment provider webhooksCheck provider, retry queue
Background job backlogQueue age past a guardrailQueue depth metricAdd workers, drain, pause producers
Backup or restore failureFirst failure of the nightly jobBackup systemRe-run, verify, escalate next day

Everything else (disk headroom on a node that has redundancy, a single pod restarting, a certificate expiring in 20 days) is a ticket or an automation target. The goal is to automate causes so that only symptoms remain (Why Focus on Symptoms, Not Causes?). Nobody on a small team is going to automate everything, so pick the three noisiest causes and write a script for those.

Give every alert a named owner and a runbook

An alert that fires without a runbook forces the person who was woken to become an investigator at 3 a.m. That is the real cost of poor on-call design: longer outages and slower recovery because everyone starts from zero (On-Call Rotation and Escalation Policy Guide). Incident response frameworks make the same point in a calmer setting, that the plan should state who does what and with what contact information, so there is no uncertainty during a live event (BlueVoyant).

Write one runbook per paging signal, and keep it to a single screen. A workable template:

# Alert: checkout 5xx rate above 5% for 5 minutes
Owner: payments team (primary: Dana, secondary: Luis)
What the user sees: checkout returns errors, orders are lost

1. Confirm: open the incident dashboard, check 5xx rate over last 15 min
2. Check status pages of payment provider and CDN (links)
3. If provider incident: enable the fallback processor flag, comment in #incidents
4. If our deploy: roll back with `deploy rollback checkout` (see deploy log link)
5. If neither: capture 10 sample error traces, page the payments secondary
Escalate to: Luis at 10 min, duty manager at 20 min if unresolved
Never do: database failover without the DBA on the call

The last two lines matter more than the middle. They tell the responder when to stop solo troubleshooting and when an action is off-limits. CISA's playbooks are built around the same structure, a fixed sequence of preparation, detection and analysis, containment, eradication and recovery, and post-incident work, with checklists so steps are not skipped under pressure (CISA playbooks). You do not need the federal version, but you do need the sequence written down for each alert (CISA PDF).

A useful test: someone who has never touched the service should be able to follow the runbook for the first ten minutes. If they cannot, it is too long or it skips the confirmation step.

Route to a primary and a secondary, with a clock

Paging one person is not an on-call system, it is a hope. The minimum viable structure is a primary, a secondary, and a manager or duty person behind them, with timeouts on each hop (incident.io). The primary gets the first notification. If the primary does not acknowledge within the window, the secondary gets it. If the secondary does not acknowledge, the escalation goes to the duty manager, or to a third name in a small company.

The timeouts you pick are a policy decision, and you should write them into the tool rather than trusting people to remember. A workable small-company escalation policy:

LevelWhoNotify afterHow
1Primary on callImmediatelyPush, then SMS, then phone call
2Secondary on call5 minutes unacknowledgedSame ladder
3Duty manager10 minutes unacknowledgedPhone call
4Service owner or expertWhen the primary escalates manuallyPhone, expected within 15 min

Two rules keep this honest. First, an unacknowledged page must move on automatically. Escalation policies exist precisely so silence is caught, rather than relying on a responder to notice they are stuck (On-Call Rotation and Escalation Policy Guide). Second, the primary must be able to escalate early without apology. Escalation is not an admission of failure, and teams that hesitate to wake a senior engineer lose more minutes than teams that escalate freely.

Escalation policies should not dead-end, which means every path terminates in a named human, not an email address or a channel (incident.io). A channel notification at level 4 is the same as no notification.

If you are wiring notifications from your own services, keep the routing logic out of application code and in a small handler, so the policy is one place to change. A skeleton that shows the shape:

def notify(alert, level, minutes_unacked):
    # level 1 primary, 2 secondary, 3 manager, 4 expert
    responder = policy.lookup(alert.service, level)
    send_push(responder, alert)
    send_sms(responder, alert, delay=0)
    schedule(alert, call_phone, responder, delay=60)

The point of the code is the schedule, not the transport. Anyone can send a push. The reliability comes from the fact that a human who does not respond causes the alert to move.

Quiet hours, rotation shape and fairness

Rotation design is where a small team either keeps its people or loses them. How often someone is disrupted, and whether the load is shared evenly, determines whether on-call is sustainable (Rootly). Three models cover most cases:

  • Weekly rotation. One person owns out-of-hours pages for a week, then hands off. Good for teams of four to eight where page volume is low. Predictable, and enough recovery time between turns.
  • Daily rotation. Duty changes hands every day. Good when volume is higher or when you want to avoid a whole week of broken sleep for one person. Costs context switching at each handoff.
  • Split rotation. One person covers evenings, another covers overnight, or the night block is split across a small pool. This is the model that most directly stops one person carrying every night.

The choice depends on real numbers, not preference. Pull the last four weeks of pages and count them. If the primary gets two or fewer actionable pages per shift on average, a weekly rotation with a secondary is fine. If the primary is getting five or more, a weekly rotation means one person absorbs five interruptions a night for seven nights, and you should split the week or move to daily. Google's SRE workbook is widely quoted as a benchmark of two to three actionable incidents per shift as a sustainable baseline (incident.io); treat that as a ceiling you are trying not to hit.

Quiet hours are the other lever. Two patterns work well for small companies:

  1. Tiered severity windows. Sev 1 symptoms page 24/7. Sev 2 symptoms page only between 07:00 and 22:00 in the responder's timezone, and roll to the next morning otherwise. Most small teams can survive an hour of degraded performance overnight, and the fix for a Sev 2 is usually cheap at 8 a.m. and expensive at 3 a.m.
  2. Night silence with a phone path. Non-urgent channels go quiet at night, but the primary and the escalation still fire for the five signals that genuinely matter. Quiet hours that silence everything are indistinguishable from having no monitoring.

Fairness has a second dimension beyond hours, and it is worth naming: some shifts are noisier than others. Weekends, release nights and the hours after a big migration carry more pages. Equity means rotating those shifts, not just the count of shifts (Rootly). Track pages per responder per month. If one name is consistently double the others, you have found the person who will quit first.

A small worked example. A five person engineering team, one service, roughly 30 pages a month. A weekly rotation gives each person about six pages per month, or about 1.5 per night on their week. That is inside the sustainable band, so keep weekly, add a secondary, and set quiet hours for anything below Sev 1. If page volume doubled to 60 a month, each week would carry 12 pages, and the team should move to a split week, where the primary covers 07:00 to 23:00 and a rotating night responder covers the rest.

Handoffs deserve one line in the runbook. A clean handoff means the outgoing responder posts what is open, what was mitigated but not fixed, and what to watch. Context that lives only in one person's head is lost at the switch (incident.io).

Test the path before you need it

The easiest way to discover that paging is broken is during an incident. Run a test page on purpose, monthly at first. Send a synthetic test to the primary, do not acknowledge it, and confirm that the secondary and then the manager received it within your stated timeouts. This is the same idea as tabletop exercises, which exist to test whether a plan works before an actual event, and to find gaps in roles and communication while the cost is low (Bitsight). CISA publishes ready-made tabletop packages if you want a scenario structure (CISA tabletop packages).

Do a lightweight version every month: one 30 minute walk through your top three paging signals, with the runbooks open, asking "who gets this, what do they do in the first ten minutes, and where does it escalate." Write down what was missing. Full-stakeholder tabletop exercises run two to four hours, and rapid-fire ones ten to thirty minutes, so pick the short format and run it more often (Sophos).

NIST's current incident response guidance frames the work as a lifecycle with a continuous improvement loop that feeds lessons back into preparation, detection and response (NIST SP 800-61r3, Cynomi). For a small company, that loop is the weekly page review described below. The exercise and the review are the same mechanism at different sizes.

Review pages weekly and delete what did not need a human

This is the step that separates teams whose on-call gets calmer from teams whose on-call slowly gets worse. Once a week, with the paging tool's history open, go through every page from the last seven days and sort each one into three buckets:

  1. Needed a human. The alert fired for a real user-facing symptom and someone had to make a decision or take an action. Leave it alone.
  2. Needed a human but the runbook was wrong. Same as above, but the responder improvised. Update the runbook with what they actually did.
  3. Did not need a human. The alert cleared on its own, was a duplicate, fired on a cause, or a script could have handled it. Delete it, demote it to a ticket, or write the automation.

Bucket three is where the time goes. A page that needed no action is a bug in your alerting, not a demonstration of vigilance. Symptom-based alerting exists so that pages stay meaningful; the shift toward symptoms only works if the team is willing to turn off cause alerts as automation catches up (Why Focus on Symptoms, Not Causes?).

Keep two numbers from the review: pages per week, and the share of pages in bucket three. If bucket three is more than a quarter of pages, the rotation is being worn down by noise before a single real incident happens. The practical fix is to name a page budget: pick a number of actionable pages per responder per shift that you will not accept going over, and treat every alert as a request to spend from it (incident.io).

A short checklist for the review:

CheckQuestionAction if it fails
Was this a symptom?Would a user have noticed?Demote to ticket or delete
Was the runbook used?Did the responder follow it?Fix the steps that were skipped
Did escalation work?Did timeouts fire correctly?Correct the policy or the contacts
Is the load fair?Does one name dominate the list?Rotate that shift or split the week
Did the secondary reply?Did the second hop actually happen?Test the paging path again

Once you have a paging path that works, the next gains come from watching the alerts themselves. If your services call models as part of the product, latency and error symptoms from those calls belong in the same paging list as everything else, which is one reason a single API for text, image, audio and embedding models is easier to monitor than four vendors with four status pages (Quanta Inference). And if the rotation conversation keeps ending in "we do not have anyone senior enough to escalate to," that is a staffing and process question worth an hour with someone who has built this before (a consulting call).

FAQ

FAQ

How many alerts should page a human at a small company?

Start with four to six signals that map directly to a user-facing symptom on a critical path. If you have more than that, sort them into must-page and must-not-page, and move the rest to a channel or dashboard.

What escalation timeout should we use?

Five minutes for the primary to acknowledge, five more before the secondary, and another five to ten before a manager. The exact numbers matter less than the fact that they are written into the tool and fire automatically.

How do quiet hours differ from just turning alerts off at night?

Quiet hours restrict pages for lower severity symptoms to a working window, while genuine Sev 1 symptoms still page around the clock. Turning alerts off entirely means no one learns about a real outage until customers write in.

How do we stop one person carrying every page?

Alternate the rotation, add a secondary who can actually be reached, and split the week if volume is high. Then track pages per responder per month and rotate the noisiest shifts, not just the hours.

What should the weekly review actually produce?

A list of deleted or demoted alerts, runbook edits, and at most one automation to build. If the share of pages that needed no human action is above a quarter, reducing that number is the whole agenda for the next week.

Sources

Sources

  1. Chapter 6 - Monitoring Distributed Systems
  2. Why Focus on Symptoms, Not Causes?
  3. On-Call Rotation and Escalation Policy Guide
  4. Top 8 Incident Response Plan Templates - BlueVoyant
  5. Federal Government Cybersecurity Incident and Vulnerability ... - CISA
  6. PDF Cybersecurity Incident & Vulnerability Response Playbooks - CISA
  7. On-call best practices: handoffs, schedules, and alert fatigue
  8. On-call rotation design: schedules that avoid burnout
  9. What is a Tabletop Exercise in Cybersecurity? - Bitsight
  10. CISA Tabletop Exercise Packages
  11. Security Tabletop Exercises - Sophos Trust Center
  12. SP 800-61 Rev. 3, Incident Response Recommendations and ...
  13. NIST Incident Response Life Cycle Explained - Cynomi
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles