Mở đầu — vì sao bài này quan trọng
Ở bài trước, bạn đã học cách định nghĩa SLI, SLO và SLA — tức là bạn đã biết cách đặt ra "mục tiêu độ tin cậy" cho hệ thống. Nhưng có một câu hỏi rất thực tế mà nhiều team gặp phải ngay sau khi đặt SLO: "Rồi sao nữa? Đặt SLO 99.9% xong thì làm gì với con số đó?"
Đây chính là chỗ mà error budget (ngân sách lỗi) bước vào. Error budget là công cụ biến một con số SLO khô khan thành một cơ chế ra quyết định thực tế cho cả team dev lẫn team vận hành. Nó trả lời những câu hỏi mà mọi tổ chức đều tranh cãi: Khi nào thì được phép deploy tính năng mới? Khi nào phải dừng lại để sửa độ ổn định? Ai là người có tiếng nói cuối cùng khi dev muốn ship nhanh còn ops muốn giữ hệ thống ổn định?
Nếu không có error budget, những cuộc tranh cãi này thường kết thúc bằng cảm tính, quyền lực chính trị, hoặc người nào la to hơn thì thắng. Với error budget, bạn có một con số khách quan để đưa lên bàn. Đó là lý do Google — nơi khai sinh khái niệm SRE — coi error budget policy là "hợp đồng xã hội" giữa các team. Bài này sẽ giúp bạn hiểu error budget không chỉ như một phép tính, mà như một chính sách vận hành có kỷ luật.
Khái niệm cốt lõi
Error budget là gì?
Không có hệ thống nào đạt 100% uptime — và điều quan trọng là bạn cũng không nên cố đạt 100%. Khoảng cách giữa 100% và mục tiêu SLO của bạn chính là error budget.
Công thức đơn giản:
Error budget = 100% - SLO
Nếu SLO của bạn là 99.9% (availability trong một tháng), thì error budget là 0.1%. Con số 0.1% này nghe nhỏ, nhưng khi quy đổi ra thời gian downtime cho phép, nó rất cụ thể:
| SLO | Error budget | Downtime cho phép / 30 ngày |
|---|---|---|
| 99% | 1% | ~7 giờ 12 phút |
| 99.9% | 0.1% | ~43 phút |
| 99.95% | 0.05% | ~21 phút |
| 99.99% | 0.01% | ~4 phút 20 giây |
Lưu ý quan trọng: error budget không nhất thiết tính theo thời gian (time-based). Với nhiều hệ thống hiện đại, người ta tính theo số request lỗi trên tổng số request (event-based). Ví dụ nếu một tháng có 100 triệu request và SLO là 99.9%, thì bạn được phép có tối đa 100.000 request lỗi. Cách tính event-based thường phản ánh trải nghiệm người dùng chính xác hơn.
Period — tính ngân sách trong khoảng thời gian nào?
Error budget luôn gắn với một period (chu kỳ). Có hai cách phổ biến:
- Calendar-based (theo lịch): reset vào đầu mỗi tháng. Đơn giản, dễ giải thích cho stakeholder, nhưng có nhược điểm là một sự cố cuối tháng có thể "được xóa nợ" ngay khi sang tháng mới.
- Rolling window (cửa sổ trượt), thường là 28 ngày hoặc 30 ngày: luôn nhìn về 28 ngày gần nhất. Phản ánh chính xác hơn tình trạng sức khỏe hiện tại của hệ thống, không có hiệu ứng "reset ảo" đầu tháng. Đây là cách nhiều team SRE trưởng thành ưa dùng.
Error budget policy — phần quan trọng nhất
Đây là điểm mấu chốt mà nhiều team bỏ qua. Tính ra được con số error budget chỉ là bước một. Error budget policy mới là thứ khiến nó có tác dụng — đó là văn bản quy định rõ ràng: khi ngân sách còn nhiều thì được làm gì, và khi ngân sách cạn thì bắt buộc phải làm gì.
Một error budget policy tốt thường quy định các "ngưỡng hành động":
- Budget còn dồi dào (ví dụ > 50%): Team được tự do deploy, thử nghiệm, ship tính năng mới với tốc độ bình thường hoặc nhanh hơn. Đây là "thời điểm vàng" để đổi mới.
- Budget xuống thấp (ví dụ < 25%): Bắt đầu thận trọng. Ưu tiên review kỹ hơn, giảm tần suất deploy rủi ro, tăng tỷ lệ công việc dành cho reliability.
- Budget cạn (chạm 0% hoặc âm): Kích hoạt feature freeze — dừng mọi việc ship tính năng mới, toàn bộ nguồn lực chuyển sang sửa lỗi ổn định cho tới khi ngân sách phục hồi. Đây là điều khoản "răn đe" mạnh nhất và phải được ký kết trước, không phải bàn khi sự cố đã xảy ra.
Vì sao error budget lại giải quyết được mâu thuẫn dev vs ops?
Mâu thuẫn kinh điển trong mọi tổ chức phần mềm: dev muốn ship nhanh (thay đổi = rủi ro), ops muốn ổn định (không thay đổi = an toàn). Hai bên có động lực ngược nhau nên hay xung đột.
Error budget đặt cả hai bên vào cùng một "sân chơi" với luật rõ ràng: bạn có 43 phút downtime để "tiêu" trong tháng. Dev muốn ship nhanh? Được, miễn là còn budget. Ship ẩu làm cháy budget? Vậy thì chính dev sẽ là người bị feature freeze — hậu quả tự nhiên, không cần ops phải "cấm". Ngược lại, ops không thể vô cớ chặn deploy khi budget vẫn còn dư dả. Con số thay thế cho cãi vã.
Tình huống thực tế
Ví dụ 1: Sàn thương mại điện tử ShopFast (giả định, TP.HCM)
ShopFast là một sàn TMĐT Việt Nam với khoảng 200 triệu request/tháng vào API đặt hàng. Team đặt SLO availability 99.9% theo rolling window 28 ngày, tức error budget khoảng 200.000 request lỗi/tháng, tương đương ~40 phút downtime.
Đầu tháng 6, một đợt deploy tính năng "flash sale" gây lỗi 5xx trong 25 phút giờ cao điểm trước khi rollback. Chỉ một sự cố đã ngốn hơn 60% error budget của cả tháng. Theo policy đã ký, khi budget xuống dưới 25%, team phải chuyển 50% sprint capacity sang việc reliability và mọi deploy phải qua review của một SRE.
Kết quả: hai tuần sau đó, team không ship được tính năng "gợi ý sản phẩm" đúng hạn — nhưng thay vào đó họ thêm được canary deployment và automated rollback. Bài học rút ra: error budget không trừng phạt team, nó định hướng lại ưu tiên một cách khách quan. Trưởng nhóm không phải là người "ra lệnh dừng ship" — chính con số budget làm việc đó, nên không ai cảm thấy bị đổ lỗi cá nhân.
Ví dụ 2: Google và triết lý gốc
Chính Google — trong cuốn SRE Book — kể câu chuyện nền tảng: các team SRE và dev thường xung đột vì SRE muốn ít thay đổi (để ổn định), còn dev muốn nhiều thay đổi (để có feature mới). Google giải quyết bằng cách: nếu dịch vụ còn error budget, dev được toàn quyền tự release. Nếu cạn budget, SRE có quyền chặn release cho tới khi budget phục hồi.
Điểm tinh tế: nếu một team liên tục cạn budget, có hai khả năng — hoặc họ ship quá ẩu, hoặc SLO đặt quá cao so với thực tế nhu cầu. Cả hai đều là tín hiệu để ngồi lại đàm phán, thay vì đổ lỗi. Bài học: error budget là công cụ đối thoại dựa trên dữ liệu, không phải cây gậy trừng phạt.
Ví dụ 3: Fintech GrabPay-style (bối cảnh Đông Nam Á)
Một ví tiền điện tử kiểu Grab/Momo có hai dịch vụ với mức độ quan trọng khác nhau: API thanh toán (critical) và tính năng "lịch sử giao dịch" (non-critical). Sai lầm ban đầu của team: đặt chung SLO 99.99% cho cả hai. Kết quả là mỗi khi màn hình lịch sử giao dịch chậm — thứ người dùng hầu như không quan tâm ngay lập tức — nó lại đốt error budget và gây feature freeze cho cả API thanh toán.
Team sửa lại: tách error budget riêng cho từng dịch vụ. API thanh toán giữ 99.99% (budget ~4 phút/tháng, cực nghiêm ngặt), còn lịch sử giao dịch hạ xuống 99.5% (budget ~3,6 giờ/tháng, thoải mái hơn). Bài học rút ra: error budget phải gắn với từng user journey quan trọng, không nên gộp chung. Đặt một SLO chung cho mọi thứ vừa lãng phí nguồn lực vào chỗ không cần, vừa che mờ vấn đề ở chỗ thực sự quan trọng.
Hướng dẫn từng bước
Đây là quy trình thực tế để thiết lập và vận hành error budget cho một dịch vụ:
Bước 1 — Xác nhận SLI và SLO đã có. Error budget được suy ra từ SLO, nên bạn phải có SLO trước. Ví dụ: SLI = tỷ lệ request trả về HTTP thành công dưới 300ms; SLO = 99.9% trong 28 ngày rolling.
Bước 2 — Tính error budget cụ thể. Quy đổi SLO thành con số bạn có thể theo dõi hằng ngày. Với 99.9% và ~100 triệu request/tháng: budget = 100.000 request lỗi. Ghi rõ cả dạng phần trăm lẫn dạng tuyệt đối để dễ giao tiếp.
Bước 3 — Đo lường budget đã tiêu (burn). Dựng dashboard hiển thị: tổng budget, đã tiêu bao nhiêu, còn lại bao nhiêu phần trăm. Thêm chỉ số burn rate — tốc độ tiêu ngân sách so với mức "bình thường". Burn rate = 1 nghĩa là đang tiêu đúng nhịp để hết budget vừa đúng cuối period; burn rate = 10 nghĩa là bạn sẽ cháy budget nhanh gấp 10 lần bình thường (báo động khẩn).
Bước 4 — Viết error budget policy thành văn bản. Đây là bước quan trọng nhất và hay bị bỏ. Ghi rõ các ngưỡng và hành động tương ứng (ví dụ ở phần khái niệm). Quan trọng: policy phải được ký kết trước bởi cả engineering lead, product owner và SRE — trước khi có sự cố. Ký khi "hòa bình" thì mới khách quan.
Bước 5 — Gắn alert theo burn rate. Đừng chỉ báo động khi budget đã cạn. Dùng multi-window multi-burn-rate alert: cảnh báo sớm khi burn rate cao trong thời gian ngắn (ví dụ tiêu 2% budget trong 1 giờ) để kịp phản ứng trước khi mất hết ngân sách.
Bước 6 — Review định kỳ. Mỗi cuối period (hoặc trong retrospective sprint), nhìn lại: budget dùng hết chưa, dùng vào việc gì, SLO có còn hợp lý không. Nếu tháng nào cũng dư budget quá nhiều → SLO có thể đang quá thấp, hoặc bạn đang "over-engineer" độ ổn định. Nếu tháng nào cũng cháy → SLO quá tham vọng hoặc chất lượng release có vấn đề.
Lỗi thường gặp & mẹo
Lỗi 1 — Tính ra budget nhưng không có policy. Đây là lỗi phổ biến nhất. Team dựng dashboard đẹp, thấy budget còn 12% mà... không làm gì cả, vẫn ship như thường. Không có policy ký trước thì error budget chỉ là con số trang trí. Mẹo: policy quan trọng hơn dashboard.
Lỗi 2 — Coi feature freeze là hình phạt. Nếu team cảm thấy bị "phạt" khi cháy budget, họ sẽ tìm cách lách: giấu lỗi, không khai báo sự cố, chỉnh SLI cho đẹp. Mẹo: đóng khung feature freeze như một cơ chế tự động khách quan, không nhắm vào cá nhân. Kết hợp với văn hóa blameless (bài 34).
Lỗi 3 — Một SLO chung cho mọi thứ. Như ví dụ fintech ở trên: gộp dịch vụ critical và non-critical vào chung một budget khiến bạn vừa lãng phí vừa che giấu vấn đề. Mẹo: mỗi user journey quan trọng nên có SLO và budget riêng.
Lỗi 4 — Đặt SLO quá cao "cho oai". Nhiều team đặt 99.99% vì nghe hoành tráng, nhưng thực tế người dùng không phân biệt được 99.9% và 99.99%. Mỗi "số 9" thêm vào làm chi phí tăng theo cấp số nhân. Mẹo: đặt SLO đủ tốt để người dùng hài lòng, không hơn — dư budget là dư nguồn lực để đổi mới.
Lỗi 5 — Quên tính cả downtime theo kế hoạch. Bảo trì có kế hoạch cũng tiêu budget (trừ khi bạn định nghĩa loại trừ rõ ràng trong SLI). Mẹo: thống nhất trước về việc maintenance window có tính vào budget hay không.
Mẹo vàng: Dùng burn rate làm ngôn ngữ giao tiếp với management. Câu "chúng ta đang tiêu error budget nhanh gấp 8 lần bình thường" dễ tạo hành động hơn nhiều so với "hệ thống hơi chậm".
Bài tập thực hành
- Tính toán: Dịch vụ của bạn có SLO 99.95% availability, period rolling 30 ngày. Hãy tính error budget quy ra phút downtime cho phép. Nếu tuần đầu tiên đã có một sự cố downtime 8 phút, bạn đã tiêu bao nhiêu phần trăm budget?
- Event-based: Một API xử lý 500 triệu request/tháng, SLO 99.9%. Tính số request lỗi tối đa được phép. Nếu tính đến giữa tháng đã có 400.000 request lỗi, burn rate hiện tại là bao nhiêu (so với mức tiêu tuyến tính đều)?
- Viết policy: Soạn một error budget policy 1 trang cho một dịch vụ giả định, gồm tối thiểu 3 ngưỡng hành động (budget > 50%, < 25%, và = 0%). Ghi rõ ai là người phê duyệt policy này.
- Phản biện: Một product manager nói: "Tháng này còn dư 60% error budget, sao team lại không ship thêm feature mà cứ ngồi fix bug ổn định?" Bạn sẽ trả lời thế nào cho đúng tinh thần error budget?
- Thiết kế alert: Đề xuất hai ngưỡng multi-burn-rate alert cho dịch vụ SLO 99.9%: một cảnh báo "khẩn cấp" (page ngay) và một cảnh báo "cần chú ý" (ticket). Nêu rõ burn rate và cửa sổ thời gian cho mỗi cái.
Tóm tắt
Error budget là cầu nối biến SLO từ một con số trừu tượng thành cơ chế ra quyết định thực tế. Những điểm cần nhớ:
- Error budget = 100% − SLO. Đó là "ngân sách lỗi" bạn được phép tiêu trong một period (calendar tháng hoặc rolling 28 ngày). Có thể tính theo thời gian downtime hoặc theo số request lỗi.
- Error budget policy quan trọng hơn phép tính. Phải ghi thành văn bản, quy định rõ hành động ở từng ngưỡng budget, và được ký kết trước bởi cả dev, product và SRE — khi chưa có sự cố.
- Feature freeze khi cạn budget là cơ chế khách quan giải quyết mâu thuẫn dev-vs-ops: còn budget thì tự do ship, cạn budget thì dừng lại sửa ổn định.
- Theo dõi burn rate, không chỉ số dư. Burn rate là ngôn ngữ giao tiếp mạnh để báo động sớm và thuyết phục management.
- Mỗi user journey quan trọng nên có budget riêng. Đừng gộp critical và non-critical vào chung một SLO.
- Dư budget đều đặn là tín hiệu SLO có thể đang quá cao — bạn đang lãng phí nguồn lực vào độ ổn định mà người dùng không cần. Cạn budget liên tục là tín hiệu cần đàm phán lại, không phải trừng phạt.