Incident Postmortem: cách viết báo cáo sự cố production để hệ thống tốt hơn sau mỗi lần lỗi
Incident postmortem là báo cáo kỹ thuật sau một sự cố production nhằm trả lời: người dùng bị ảnh hưởng thế nào, timeline xử lý ra sao, vì sao hệ thống cho phép lỗi xảy ra, và đội ngũ sẽ thay đổi gì để lỗi tương tự khó lặp lại hơn. Một postmortem tốt không phải để tìm người có lỗi; nó biến incident thành dữ liệu cải tiến reliability.

Khi nào cần viết incident postmortem?
Không phải mọi bug đều cần postmortem dài. Nhưng nếu sự cố chạm tới availability, data correctness, security, latency nghiêm trọng, hoặc làm đội on-call phải can thiệp thủ công, nên có một bản postmortem ngắn nhưng có cấu trúc.
- API 5xx tăng vượt SLO trong nhiều phút.
- Database lock, deadlock hoặc migration làm request timeout.
- Queue backlog khiến email, thanh toán, webhook, đồng bộ dữ liệu bị trễ.
- Deploy rollback vì lỗi không được phát hiện ở staging/test.
- Alert không kêu, dashboard sai, hoặc team phát hiện lỗi từ khách hàng trước hệ thống monitoring.
Cấu trúc postmortem cho đội backend/DevOps
1. Summary: nói thẳng impact trong 5-7 dòng
Summary không nên mở đầu bằng “hệ thống gặp một số vấn đề”. Hãy ghi cụ thể: dịch vụ nào lỗi, từ mấy giờ đến mấy giờ, bao nhiêu request/user bị ảnh hưởng, triệu chứng người dùng thấy là gì, trạng thái hiện tại đã recover chưa.
Summary mẫu:
Từ 09:42 đến 10:18 ICT, endpoint POST /orders có tỷ lệ 5xx tăng từ 0.1% lên 18%.
Khoảng 3.200 lượt tạo đơn bị retry hoặc thất bại. Nguyên nhân trực tiếp là connection pool cạn sau deploy worker mới tạo transaction dài. Dịch vụ đã recover lúc 10:18 sau khi rollback worker và tăng timeout guard.
2. Impact: đo bằng ngôn ngữ hệ thống và người dùng
Impact nên tách technical impact và user/business impact. Với backend, đừng chỉ ghi “service down”; hãy ghi tỷ lệ lỗi, latency p95/p99, queue lag, số job retry, số bản ghi cần reconcile. Đây là dữ liệu giúp ưu tiên action item sau incident.
3. Timeline: mốc thời gian phải kiểm chứng được
Timeline nên lấy từ log, alert, deploy event, incident channel, APM trace, database metrics. Nếu một mốc chỉ dựa vào trí nhớ, đánh dấu rõ để kiểm lại.
| Thời điểm | Sự kiện | Nguồn |
|---|---|---|
| 09:41 | Deploy version 2026.05.25.1 | CI/CD release log |
| 09:42 | p95 latency /orders tăng lên 4.8s | APM dashboard |
| 09:47 | Alert 5xx fired trong PagerDuty | Alert log |
| 10:05 | Rollback worker xử lý outbox | Deploy log |
| 10:18 | Error rate về baseline | Metrics |

Root cause khác contributing factors như thế nào?
Nhiều postmortem yếu vì cố tìm “một root cause” duy nhất. Production incident thường là chuỗi điều kiện: code path mới, migration chưa tối ưu, alert thiếu ngưỡng, dashboard không có cardinality đúng, runbook lỗi thời, hoặc review bỏ sót failure mode.
Ví dụ phân tích tốt hơn “do developer deploy bug”
- Trigger: worker mới mở transaction quanh cả bước gọi API ngoài.
- Failure mode: transaction giữ connection lâu, pool của web process bị cạnh tranh.
- Detection gap: chưa có alert theo database connection saturation.
- Prevention gap: code review checklist chưa yêu cầu kiểm tra transaction boundary cho worker có I/O ngoài.
- Recovery gap: runbook rollback worker chưa ghi cách drain queue an toàn.
Action items: phần quan trọng nhất của incident postmortem
Action item phải có owner, deadline, cách verify và liên kết tới failure mode. Nếu action item chỉ là “cẩn thận hơn khi deploy”, coi như không có action item.

Checklist action item đáng tin
- Có owner cụ thể, không phải “team backend”.
- Có due date thực tế theo mức độ rủi ro.
- Có loại việc: fix code, test, monitor, runbook, process, architecture.
- Có điều kiện hoàn thành đo được: test pass, alert chạy, dashboard có metric, game day hoàn tất.
- Có link ticket/PR/runbook để audit sau này.
Action item tốt:
[Owner: An] Tách external API call ra khỏi DB transaction trong OrderOutboxWorker.
Due: 2026-05-28.
Verify: integration test mô phỏng API timeout 30s; metric db_pool_wait p95 không vượt 100ms khi worker retry.
Link: PR #1842, dashboard /db-pool.
Postmortem blameless không có nghĩa là vô trách nhiệm
Blameless nghĩa là không dừng ở việc đổ lỗi cá nhân, vì đổ lỗi làm team giấu thông tin. Nhưng postmortem vẫn phải rõ trách nhiệm hệ thống: ai follow action item, ai review, ai chấp nhận rủi ro còn lại. Văn hóa tốt là nói thật về failure mode mà không biến báo cáo thành phiên tòa.
Template ngắn có thể dùng ngay
# Incident Postmortem
## Summary
## Customer/User Impact
## Timeline
## What went well
## What went wrong
## Root cause / contributing factors
## Detection gaps
## Recovery notes
## Action items
| Action | Owner | Due | Verify | Link |
## Follow-up review date
Liên kết với các thực hành production engineering khác
Postmortem có giá trị nhất khi nối với observability, deploy, database migration và API reliability. Nếu team đã có checklist deploy backend lên production, hãy bổ sung bài học incident vào checklist đó. Với lỗi giao dịch phân tán hoặc retry, đọc thêm outbox pattern trong backend và idempotency API. Nếu incident liên quan database, đối chiếu với database migration zero downtime. Với hệ microservices, distributed tracing giúp timeline chính xác hơn.
Kết luận
Một incident postmortem tốt giúp team production engineering học nhanh hơn tốc độ hệ thống phức tạp lên. Hãy viết ngắn, có số liệu, có timeline kiểm chứng, có contributing factors trung thực và có action item đóng được. Nếu sau một tháng không action item nào được verify, đó không phải postmortem; đó chỉ là biên bản sự cố.