Version: 1.0
Designed for: small engineering team
Goal: enough risk control to make SLA promises realistic without creating enterprise bureaucracy
For a small team, risk management must be simple.
You do not need a large framework, many documents, or long meetings.
You need one living document that answers:
- What are we promising?
- What can break this promise?
- How will we know?
- What will we do?
- Who owns it?
- What is missing?
If a risk does not help answer one of these questions, do not track it.
This Docs should contain only five sections:
1. Product promises
2. Critical flows
3. Top risks
4. Runbooks
5. Missing work
That is enough for a small team.
Write only the promises that matter.
Example:
## Product promises
| ID | Promise | Target | How we measure it |
|---|---|---:|---|
| P1 | API is available | 99.9% monthly | successful synthetic/API requests |
| P2 | Accepted events are not lost | 0 lost accepted events | accepted vs processed/replayed count |
| P3 | Jobs complete in reasonable time | 99% within 30 min | job duration metric |Rules:
- Maximum 3-5 promises.
- Each promise must be measurable.
- Do not write promises you cannot measure.
- Separate availability from data loss.
Bad:
System should be stable.
Good:
After we return success to the client, the accepted item must be stored and replayable.
Track only the flows that can seriously hurt users or business.
Example:
## Critical flows
| Flow ID | Flow | Success means | Main dependencies |
|---|---|---|---|
| F1 | Receive customer event | event is durably stored before success response | API, database/queue, auth |
| F2 | Process job | job finishes or is retryable | worker, queue, database, external provider |
| F3 | User reads result | user sees correct result | API, database, frontend |Rules:
- Maximum 3-7 flows.
- Do not model every feature.
- If nobody cares during an outage, it is not critical.
Track only the top 10 risks.
This is the core of the framework.
## Top risks
| ID | Risk | Flow | Impact | Chance | Detection | Recovery | Owner | Status |
|---|---|---|---:|---:|---|---|---|---|
| R1 | Bad deploy breaks API | F1/F3 | 4 | 3 | synthetic check, 5xx alert | rollback | A | controlled |
| R2 | Database unavailable | F1/F2/F3 | 5 | 2 | DB errors, latency alert | failover/retry/manual mode | B | needs drill |
| R3 | External provider timeout | F2 | 3 | 4 | job failure/backlog alert | retry, pause provider | C | controlled |
| R4 | Accepted event not processed | F1/F2 | 5 | 2 | accepted vs processed gap | replay from durable store | A | missing alert |
| R5 | Only one person knows recovery | all | 4 | 4 | review | write/test runbook | team | open |Use only two numbers.
| Score | Meaning |
|---|---|
| 1 | internal inconvenience |
| 2 | small user impact |
| 3 | degraded product |
| 4 | outage or serious customer impact |
| 5 | data loss, security issue, financial/legal damage |
| Score | Meaning |
|---|---|
| 1 | very unlikely |
| 2 | unlikely |
| 3 | possible |
| 4 | likely |
| 5 | frequent |
Priority:
priority = impact * chance
Simple rule:
| Priority | Action |
|---|---|
| 1-6 | track only |
| 7-12 | needs control |
| 13-25 | must be fixed, reduced, or explicitly accepted |
Use only these statuses:
| Status | Meaning |
|---|---|
| open | known, not controlled |
| controlled | alert + recovery path exist |
| accepted | team/business accepts it |
| missing data | cannot estimate yet |
| needs drill | runbook exists but not tested |
Only high-impact risks need runbooks.
Use this short format:
## Runbook R1: Bad deploy breaks API
Symptoms:
- 5xx alert
- synthetic check failing
- user reports
First action:
- check if deployment happened in last 30 minutes
Recovery:
1. rollback to previous version
2. verify synthetic check
3. check error rate
4. post update in incident channel
Data check:
- confirm no accepted data was lost
- replay failed/stuck items if needed
Owner:
Primary: A
Backup: BRules:
- Maximum 5-10 runbooks.
- Each runbook must fit on one screen.
- It must say what to do first.
- It must say how to verify recovery.
- It must say whether data may be affected.
This is the most important section for a small team.
It shows what prevents you from trusting your SLA.
## Missing work
| Item | Why it matters | Related risk | Owner | Priority |
|---|---|---|---|---|
| No event replay dashboard | cannot prove accepted events are processed | R4 | A | high |
| DB restore not tested | recovery time unknown | R2 | B | high |
| No provider backlog alert | provider outage detected too late | R3 | C | medium |
| Only A can rollback | bus factor risk | R1/R5 | team | high |Rules:
- Maximum 10 items.
- Every item needs owner.
- No owner means it will not happen.
- Review this weekly.
15 minutes once per week.
Agenda:
1. Did anything break last week?
2. Did any top risk change?
3. Are we missing any new risk?
4. What is the highest missing work item?
5. Who does one concrete thing this week?
That is all.
Do not turn this into a long meeting.
30 minutes once per month.
Agenda:
1. Are our promises still realistic?
2. Did we exceed error budget?
3. Are top 10 risks still the right top 10?
4. Did we test at least one recovery path?
5. Is there any one-person-only knowledge?
Pick one small drill per month:
- rollback drill
- restore drill
- replay drill
- external provider outage simulation
- expired secret/cert simulation
- worker down simulation
For each product promise, ask:
Can we detect failure?
Can we recover fast enough?
Can we prove data is safe?
Can more than one person do the recovery?
If the answer is no, then the SLA is not proven.
For 30 days:
| SLA | Allowed downtime |
|---|---|
| 99% | 432 min |
| 99.5% | 216 min |
| 99.9% | 43.2 min |
| 99.95% | 21.6 min |
| 99.99% | 4.32 min |
Simple rule:
If one realistic incident recovery takes longer than the monthly downtime budget,
the SLA is not realistic without redesign or explicit risk acceptance.
Example:
SLA: 99.9%
Allowed downtime: 43.2 minutes/month
Known manual recovery: 2 hours
Conclusion: 99.9% is not proven.
Availability and data loss are different.
A system can be available and still lose data.
For any accepted user/customer input, answer:
Do we store it before returning success?
Can we retry processing?
Can we detect stuck items?
Can we replay safely?
Can we prove accepted count equals processed/replayed/failed count?
If not, data-loss risk is uncontrolled.
Minimum safe pattern:
receive request/event
-> validate
-> durable write
-> return success
-> process async
-> mark complete or failed
-> replay if needed
For each critical flow, list only the dependencies that can break it.
Use this small table:
## Dependency check
| Flow | Dependency | If it fails | Fallback | Status |
|---|---|---|---|---|
| F1 | database/queue | cannot safely accept events | no | high risk |
| F2 | external provider | jobs delayed | retry later | controlled |
| F3 | auth provider | users cannot log in | no | accepted |Rule:
If a dependency is required and has no fallback, your product inherits its failure risk.
But do not over-model. Track only dependencies used by critical flows.
During incident:
1. Say who is incident lead.
2. Stop risky deploys.
3. Check recent changes.
4. Use runbook.
5. Restore service.
6. Check data safety.
7. Write short incident note.
After incident, write only this:
## Incident note
Date:
Impact:
Duration:
Root cause:
What fixed it:
What was missing:
Risk updated:
Action item:
Owner:If an incident does not update the risk file, the team learned nothing.
This small framework is done when:
- product promises are listed
- 3-7 critical flows are listed
- top 10 risks are listed
- each risk has owner and status
- high risks have tiny runbooks
- missing work is visible
- team reviews it weekly for 15 minutes
- at least one recovery path is tested monthly
For any new service, feature, or dependency, ask only this:
1. Which product promise depends on it?
2. Which critical flow uses it?
3. What happens if it is down, slow, or wrong?
4. How do we detect that?
5. How do we recover?
6. Can we recover within our SLA?
7. Can more than one person do it?
8. What is missing?
If you can answer these questions, the risk is controlled enough for a small team.
If not, add it to "Missing work".