How Should a Solo Developer or Small Team Handle Incidents?
A solo developer or a small team handles incidents well by doing three small things every time: get one clear alert to one named person, acknowledge it so everyone knows someone is on it, and resolve it with a short note that says what happened. You do not need an on-call rota, a war room, or a 40-page runbook. You need a monitor that notices, an escalation chain with two or three steps, and the discipline to acknowledge and resolve every incident, even the boring ones.
This guide is for people who run production systems without a dedicated operations team: indie hackers, agencies with a handful of client sites, two-person startups, and side projects with real users. It covers what "incident practice" actually means at that scale, how to build an escalation chain that does not depend on one person always being awake, why acknowledge and resolve are worth doing even when you are the only one who will ever read the timeline, and when a public status page earns its keep.
What does an incident even mean for a tiny team?
Enterprise on-call vocabulary is heavy: severity matrices, incident commanders, bridge calls, post-incident review boards. Most of that exists to coordinate dozens of people. When it is just you, or you and a co-founder, the coordination problem is much smaller, but the underlying questions are exactly the same:
- Did anyone notice? A site can be down for hours before a customer emails you. Detection is the first job.
- Does anyone own it right now? Two people both assuming the other one is looking is the classic small-team failure.
- Is it over, and what changed? Without a resolve step, "I think it fixed itself" becomes the permanent record.
So a useful definition for a small team is: an incident is any time a monitor says something is wrong and a human has to decide what to do about it. That includes false alarms. Treating a false alarm as an incident (acknowledge, look, resolve with the note "flaky check, raised the timeout") is how you find out your monitoring needs tuning, instead of learning to ignore it.
Step one: one alert, to a place you will actually see it
The most common small-team mistake is not a missing monitor. It is an alert that fires into a place nobody looks: an inbox with 4,000 unread messages, a Slack channel that is muted after 9pm, or an email address that stopped forwarding when you switched providers. If you have not already, read how to get notified when your website goes down for the mechanics of setting up an HTTP check. The short version:
- Monitor the thing users touch (the public URL, not just the server ping).
- Alert on a channel that produces a phone notification, not just an unread badge.
- Require two or three consecutive failures before alerting so a single blip does not wake you.
Pingwire's uptime monitors deliver a push notification to your phone when a check fails and open an incident record at the same time, so the alert and the thing you acknowledge are the same object. That linkage matters more than it sounds: when the alert is just a message and the incident is a row somewhere else, people acknowledge in one place and forget the other.
Step two: an escalation chain with two or three steps
An escalation policy answers the question "what if the first person does not respond?" For a large team the answer is a rota. For a small team the honest answer is usually one of these:
- Try me again, louder, a few minutes later.
- Then try my co-founder or the one other person who has server access.
- Then post to a shared channel or fire a webhook at something else that can make noise.
That is the whole chain, and it is enough. The key property is that every step is a different way of reaching a human, and the last step repeats until someone acknowledges. Here is what creating that policy looks like with the Pingwire REST API (any pw_live_ key with send scope works; see the developer docs for auth details):
curl -sS https://pingwire.dev/api/v1/escalations \
-H "Authorization: Bearer $PINGWIRE_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "prod-web",
"repeat_last": true,
"steps": [
{ "target_type": "user", "user_id": 12, "delay_minutes": 5 },
{ "target_type": "user", "user_id": 27, "delay_minutes": 10 },
{ "target_type": "conversation", "conversation_id": 340, "delay_minutes": 15 }
]
}'
Read it top to bottom: the incident opens and step one pings user 12 immediately. If nobody has acknowledged after 5 minutes, step two pings user 27. After a further 10 minutes, step three posts into a shared conversation, and because repeat_last is on, that last step keeps repeating on its delay until the incident is acknowledged or resolved. Steps can also target a webhook URL, which is how you hand the incident to another system if you already have one.
Two design notes that come from real pain. First, a target that does not resolve is refused when you save the policy, not discovered at 3am when it fails to page anyone. Second, steps are replaced as a whole list, not patched one at a time, so the runner never reads a chain that is half-edited. If you build your own escalation logic on a cron job (many small teams start there, and it is a fine place to start), copy both of those properties.
What if there is genuinely only one of you?
Then the chain is: push to your phone, push again 5 minutes later, then keep repeating every 15 minutes until you acknowledge. You cannot escalate to a person who does not exist, but you can make sure a single missed notification does not become a silent outage. The repeat is the whole point. Add a second target the day you have a second person.
Step three: acknowledge, even when it is only you
Acknowledging an incident does two things. It stops the escalation chain, so your co-founder is not woken up for something you are already looking at. And it writes a timestamped event into the incident timeline: "acknowledged by alice at 02:14". On a two-person team that second part is what prevents the "I thought you had it" conversation. On a one-person team it is your own memory: three weeks from now you will not remember whether you looked at the 2am alert or slept through it.
Make acknowledging cheap. It should be one click in the incident dashboard or one API call from wherever you are:
curl -sS -X POST https://pingwire.dev/api/v1/incidents/8813/acknowledge \
-H "Authorization: Bearer $PINGWIRE_KEY"
Because that endpoint is on the REST API, it also works from an AI agent through the MCP connector, which is handy if you have a script or an assistant triaging your alerts before you get to them (see how an AI agent can send you a push notification for that pattern in the other direction).
Step four: resolve with one sentence
Resolution is where small teams cut corners, and it is the corner most worth keeping. When the check goes green again, the incident auto-resolves and the timeline records it; that is fine and you should let it. But write one sentence of your own before you move on. Where you write it matters less than that you write it: a team wiki, a pinned message in your shared channel, or a note to yourself sent from the CLI with the incident id in it. For example:
- "Disk full on db host, cleared old backups, added a disk monitor."
- "Cert renewal cron silently failing since the 3rd, renewed by hand, fixed the cron."
- "False alarm, upstream DNS hiccup, no action."
That sentence is your entire post-mortem. Over a few months those sentences become the most valuable operational document you own: a list of what actually breaks, in your words, next to the times it broke. It is also what turns "the site is flaky" into "the site went down four times and three of them were the same cron job", which is a fixable statement.
Do you need a public status page?
Not on day one. A status page is for the moment when more than a handful of people would otherwise email or message you during an outage. The signal that you have reached that point is usually the second time you find yourself typing the same "we know, we're on it" reply to different people.
When you do want one, keep it honest and boring: a short list of the components users care about, their current state, and the open incident if there is one. Pingwire's public status pages are built from your existing monitors, so the page reflects the same checks that alert you, and each page has a public URL you can share or rotate. Rotating the token revokes the old link, which is useful when a page was meant for one client and you want to hand out a fresh one.
A minimal incident practice, written out
If you want something you can paste into your team notes, here it is:
- Every public URL has an uptime monitor. Alerts go to a channel that pushes to a phone.
- Every monitor is attached to an escalation policy with at least a repeat step; with two people, the second step is the other person.
- Whoever sees the alert first acknowledges it. Acknowledging means "I own this", not "I fixed this".
- When it is over, whoever owned it writes one sentence about what happened, in one agreed place.
- Once a month, read those sentences. If the same sentence appears twice, that is your next engineering task.
Everything else, severity levels, runbooks, status pages, comes later, and only if the notes tell you it is needed. Google's SRE book has a good chapter on managing incidents that is worth reading for the principles, but do not confuse its scale with yours. Small teams do not fail at incidents because they lack process. They fail because nobody noticed, nobody owned it, or nobody wrote down what happened. Fix those three, and you are ahead of most teams ten times your size.
Frequently asked questions
Do I need an on-call rotation if I am a solo developer?
No. A rotation exists to share load between many people. As a solo developer, use an escalation policy that pushes to your phone, repeats after a few minutes, and keeps repeating until you acknowledge, so one missed notification does not become a silent outage. Add a second person to the chain the day you have one.
What is the difference between acknowledging and resolving an incident?
Acknowledging means a named person owns the incident right now; it stops the escalation chain and timestamps who took it. Resolving means the problem is over. Monitors usually auto-resolve when the check passes again; you add the human sentence about what actually happened.
How many escalation steps should a small team have?
Two or three. Step one alerts the first responder immediately, step two tries a second person or the same person again after a few minutes, and the last step posts to a shared channel or webhook and repeats until someone acknowledges. More steps rarely help when there are only a few people to reach.
When should a small team publish a status page?
When more than a handful of users would otherwise contact you directly during an outage. A good signal is the second time you type the same 'we know, we are on it' reply to different people. Before that, a status page is extra upkeep with little payoff.
Should false alarms be treated as incidents?
Yes. Acknowledge, look, and resolve with a note such as 'flaky check, raised the timeout'. Treating false alarms as incidents is how you discover that your monitoring needs tuning, instead of slowly learning to ignore alerts.
Try Pingwire
Send your first alert in under 30 seconds — one HTTP call, straight to a chat and your phone.