Skip to content
Un runbook de incident pentru o echipă fără on-call
← ← Înapoi la Idei Cloud

Un runbook de incident pentru o echipă fără on-call

Companiile mari au rotații de on-call, incident commanderi, matrici de severitate și un buget de tooling pe măsură. O echipă de trei are un chat de grup și pe cine e treaz. Echipa aia tot are incidente, și tot se întâmplă la 02:40, iar întrebarea nu e dacă să ai un proces, ci cât de puțin proces captează cea mai mare parte din valoare. Asta e ce am scris pentru o echipă de trei oameni care rulează o platformă de plăți, ce citim în timpul unui incident și ce scriem după. Totul încape pe două pagini, intenționat.

Ce decidem înainte, ca să nu decidem la 02:40

Cele mai proaste decizii de incident sunt cele luate sub presiune de cineva abia trezit. Așa că numărul mic de decizii care contează sunt luate dinainte și scrise acolo unde trimite alerta.

Severitatea, în trei rânduri.

Nivel Definiție Răspuns
S1 Utilizatorii nu pot face lucrul pentru care plătesc: checkout-ul pică, login-ul pică, datele sunt greșite Acum. Cine vede acționează. Trezești pe cineva dacă e nevoie.
S2 Degradat: lent, o funcție stricată, erori pentru unii utilizatori Într-o oră ziua, dimineața următoare noaptea
S3 Intern: un job a picat, un dashboard e greșit, ceva ce nu vede utilizatorul Următoarea zi lucrătoare

Rostul tabelului nu e precizia. E că „ăsta e S1?” are un răspuns de un rând, iar răspunsul decide dacă suni pe cineva.

Cine e primul care răspunde săptămâna asta. Nu o rotație cu tooling; un nume în topic-ul canalului, schimbat lunea. Persoana aia ține telefonul deschis și se uită prima. Toți ceilalți sunt al doilea. E best-effort, și o spunem, și n-a fost niciodată o problemă, pentru că alternativa, nimeni să nu fie sigur cine se uită, e mai rea decât orice răspuns imperfect.

Prima regulă: dai înapoi înainte să depanezi. Dacă a fost un deploy în ultimele ore și simptomul a început după el, rollback-ul e o schimbare de tag și durează patru minute. Fă asta întâi. Depanarea vine după, pe staging, cu incidentul închis. De câte ori rollback-ul a fost decizia greșită: zero. De câte ori depanarea întâi a costat o oră în plus de pană: de trei ori, toate înainte să scriem regula.

Pagina de runbook per alertă

Fiecare alertă care poate suna trimite la o pagină, și fiecare pagină are aceleași cinci titluri. Iată cea reală pentru alerta de rată de erori, ușor cenzurată.

ApiErrorBudgetBurn · runbook Ce înseamnăapi-ul întoarce 5xx la mai mult de 1,4 % din request-uri, pe cel puțin un cloud Uită-te întâi1 · Grafana: rata de erori pe rută și cloud_provider (link) 2 · Loki: {service_name="api"} | json | level="error" (link, ultimele 15 min) 3 · ultimul deploy: ./scripts/deploy.sh --env prod --history Rollbackdacă a fost un deploy în ultimele 4 h: ./scripts/deploy.sh --env prod --rollback --yes · 4 min Cauze cunoscute2026-03 · connection reset la billing → scale-in Aurora, rezolvat cu idle timeout pe pool 2026-05 · 504 după deploy → warm-up, rezolvat cu health check HTTP Cui spui#incidents, un rând în 5 min · pagina de status: ./scripts/status.sh degraded

Cinci titluri. Ce înseamnă e o propoziție, pentru că numele alertei nu ajunge niciodată la 02:40. Uită-te întâi sunt exact trei lucruri, fiecare un link sau o comandă, în ordinea care găsește cauza cel mai repede; peste trei și oamenii sar lista. Rollback e comanda exactă și condiția de folosire. Cauze cunoscute e memoria acumulată a echipei: fiecare incident trecut pe alerta asta, cu ce l-a rezolvat, un rând fiecare. Cui spui e canalul și pagina de status.

Secțiunea Cauze cunoscute e cea care crește și cea care plătește. Jumătate din incidentele noastre sunt repetări a ceva din lista aia, iar pentru ele timpul de la alertă la rezolvare e timpul cât durează să citești rândul.

Ce citim la 02:40

Alerta. Are link-ul de runbook în ea, pentru că regula de alertă poartă o adnotare cu URL-ul. Apoi pagina de runbook. Apoi cele trei link-uri din Uită-te întâi, în ordine. Atât. Nu e niciun rol de incident commander de atribuit și niciun bridge de deschis, pentru că suntem trei și suntem în același chat.

Ce nu citim, intenționat: documentele de arhitectură, pagina de service health a consolei cloud, ultima lună de commit-uri. Dacă cele trei link-uri nu găsesc cauza și a fost un deploy, dai înapoi. Dacă n-a fost deploy, pasul patru e trace-ul: găsești un request eșuat și îi deschizi trace-ul, care de obicei arată spre serviciul care e stricat de fapt, nu spre cel care raportează erori.

Comunicarea, cu template-uri

Două audiențe, două template-uri, ambele scrise dinainte, ca nimeni să nu compună proză în timpul unei pene.

Intern, în #incidents, în cinci minute de la confirmare:

S1 · erori api ~3 % de la 02:31 · mă uit · ultimul deploy ieri 21:40 · dau înapoi întâi

Un rând. Severitate, simptom, de când, ce faci. Actualizezi rândul la fiecare cincisprezece minute, sau când se schimbă ceva, chiar dacă actualizarea e „încă mă uit”. Tăcerea e lucrul pe care oamenii nu-l pot tolera.

Extern, pe pagina de status, doar pentru S1:

Vedem erori crescute la checkout de la 02:31 UTC. Am identificat cauza și desfășurăm o remediere. Următoarea actualizare în 30 de minute.

Pagina de status e un fișier HTML static într-un bucket S3 în spatele CloudFront, pe un domeniu separat, cu un script care o comută între „operational”, „degraded” și „outage” și adaugă un mesaj. Nu costă nimic, nu depinde de nimic ce ar putea fi parte din incident și se actualizează cu o comandă. Un produs de status page găzduit e și el în regulă; proprietățile importante sunt să fie în afara razei exploziei și să se actualizeze în secunde.

0 · alertăcu link de runbook 2 · un rândîn #incidents 3–8 · uită-te întâitrei link-uri, în ordine deploy înultimele 4 h? da nu rollback · 4 mindepanezi după, pe staging un request eșuatdeschizi trace-ul · repari înainte minutul 15: actualizezi rândul din canal · pagina de status dacă e S1 · apoi la fiecare 15 minute până se rezolvă

Ce scriem după

O pagină, în două zile lucrătoare, fără vinovați prin construcție, pentru că are trei întrebări și niciuna nu e „cine”:

  1. Ce s-a întâmplat, ca o cronologie. Alertă la 02:31, confirmare la 02:34, rollback la 02:41, rata de erori normală la 02:45, cauza identificată la 10:20 a doua zi. Orele din canal, nu din memorie.
  2. De ce s-a întâmplat, și de ce n-a fost prins mai devreme. A doua jumătate e cea utilă. „Migrarea a blocat tabela” e cauza; „nu cronometrăm migrările pe un snapshot de staging” e golul.
  3. Ce schimbăm. Cel mult trei puncte, fiecare cu un responsabil și o săptămână. Cel mai des, de departe, punctul e un rând nou în Cauze cunoscute dintr-un runbook. Al doilea cel mai des e o alertă nouă. Al treilea e o schimbare într-un checklist.

Nota post-incident merge în repo, lângă runbook-uri, într-un folder cu data. După optsprezece luni sunt paisprezece, iar cititul lor în ordine e cel mai bun document de onboarding pe care îl avem.

Ce nu facem, și de ce e în regulă

Fără on-call formal cu politici de escaladare: trei oameni, un telefon deschis, best effort, spus clar. Fără incident commander: cine răspunde primul e ăla, iar dacă e mare o spune și se alătură altcineva. Fără severitate dincolo de trei niveluri. Fără war room. Fără ședință de postmortem fără vinovați; nota ajunge, și se discută la următorul sync obișnuit.

Toate astea sunt lucrul corect pentru o organizație de inginerie de cincizeci de oameni. Pentru trei, sunt ceremonie, iar ceremonia la 02:40 e ce îi face pe oameni să nu raporteze S2-ul care până dimineață ar fi fost S1.

Procesul încape pe două pagini: tabelul de severitate, numele primului care răspunde, regula de rollback, template-ul de runbook, cele două template-uri de mesaj, cele trei întrebări post-incident. A luat o după-amiază de scris și a fost citit, la nevoie, de paisprezece ori.

Dacă vrei cele două pagini ca punct de plecare, adaptate la stack-ul tău, le scriem împreună.