Percentile latency trong DevOps: chọn p95 hay p99 hay p99.9 khi benchmark?
Percentile latency trong DevOps: chọn p95 hay p99 hay p99.9 khi benchmark?
Thấy nhiều bác chia sẻ những bài benchmark kinh nghiệm rất thực tế nhưng có vẻ chưa có bài nào nói rõ về các con số p50, p70, p80, p90, p95, p99,…

p50/p90/p95/p99… là gì?
Đây là percentile (bách phân vị) của một tập dữ liệu đo được (thường là latency).
- p50: 50% mẫu ≤ giá trị này (median)
- p90: 90% mẫu ≤ giá trị này
- p95: 95% mẫu ≤ giá trị này
- p99: 99% mẫu ≤ giá trị này
- p99.9: 99.9% mẫu ≤ giá trị này (tức là chỉ khoảng 0.1% trường hợp chậm hơn mức này)
Ví dụ nhanh: nếu p95 = 300ms, thì 95% request ≤ 300ms, còn 5% request > 300ms.
Tại sao mọi người thấy p70/p80 nhưng tôi không liệt kê?
Nếu mới tìm hiểu thì chắc không tránh sai lầm khi ôm cả những con số này vào và làm bài toán có thể đi lệch hơn mà chưa chắc cần thiết. Về cơ bản thì vẫn dùng được nhưng thực tế ngành hay chuẩn hoá quanh p50 + p90/p95 + p99 (và đôi khi p99.9). Vì bộ này cho bạn thấy đồng thời:
- Thường thì nhanh cỡ nào (p50)
- Đa số người dùng thấy thế nào (p90/p95)
- Các trường hợp chậm bất thường nặng đến đâu (p99/p99.9)
Vì sao benchmark thường chọn percentile thay vì average?
Average (trung bình) tuy Full HD nhưng có che sự thật. Hệ thống có thể:
- Đa số request rất nhanh
- Nhưng thỉnh thoảng có request rất chậm (do cache miss, DB bị kẹt, GC, mạng chập chờn…)
Người dùng thường bực vì những lần chậm bất thường, nên DevOps/SRE quan tâm:
- p50: trải nghiệm thường gặp
- p95: trải nghiệm đa số người dùng gặp
- p99/p99.9: các lần chậm bất thường (ít gặp hơn nhưng dễ gây timeout/retry, làm mọi thứ chậm theo)
Nói ngắn gọn:
- Average trả lời trung bình ra sao
- Percentile trả lời phần lớn người dùng thấy ra sao, và lúc xấu thì xấu đến mức nào
Benchmark đo cái gì cho đúng?
Latency
Bạn cần xác định mình đang đo latency kiểu nào, vì cùng là latency nhưng ý nghĩa khác nhau:
-
End-to-end (từ phía người gọi): Từ lúc client gửi request → nhận response.
- Đúng với trải nghiệm thực tế.
- Bị ảnh hưởng bởi mạng và vị trí máy tạo tải.
-
Server-side (chỉ tính trong service): Thời gian xử lý bên trong service (không tính mạng).
- Tốt để tối ưu code/DB.
- Có thể bỏ sót chuyện đợi xếp hàng hoặc vấn đề mạng.
-
Thời gian đợi vs thời gian xử lý
Nhiều lúc chậm là do request đợi tới lượt, không phải do xử lý lâu. Nếu p95 tăng mạnh khi tải tăng, thường là đợi nhiều hơn.
Gợi ý thực tế: benchmark chuyên nghiệp thường ghi đồng thời:
- Latency end-to-end
- Latency bên trong service
- Thời gian DB/cache/external API
- Thời gian đợi trước khi được xử lý (nếu có)
- Và nếu hệ thống yêu cầu rất cao, có thể theo dõi thêm p99.9 để bắt các lần siêu hiếm nhưng siêu chậm.
Throughput + Error (đi kèm bắt buộc)
Percentile đẹp mà lỗi cao là benchmark không dùng được.
- RPS/throughput
- Error rate (5xx/timeouts)
- Retry count (retry có thể làm kết quả nhìn ảo)
Saturation (để giải thích vì sao)
Nhìn thêm để biết tại sao chậm:
- CPU, memory, GC
- DB connections, thread pool, queue depth
- IO wait, network RTT/loss
- Cache hit rate
Theo tôi, benchmark tốt là benchmark giải thích được nguyên nhân, không chỉ nêu con số.
Những usecase thực tế áp dụng Percentile
Use case 1: Benchmark API/service khi đổi code hoặc infra
Mục tiêu: Bản mới có chậm hơn bản cũ không, ở mức tải X?
Cách làm chuẩn (dựa vào kinh nghiệm của tôi):
- Chạy cùng workload, cùng kiểu tạo tải
- So sánh p50/p90/p95/p99 (và p99.9 nếu cần) + throughput + error
- Nếu p95 tăng mà p50 không tăng thì thường là có vấn đề ở rare path/tail path (ví dụ cache miss, GC, lock contention…)
Ví dụ:
v1: p50 40ms, p95 120ms, p99 250ms
v2: p50 42ms, p95 160ms, p99 600ms
Kết luận: Majority vẫn ổn, nhưng tail latency tệ hơn nhiều thì rủi ro timeout/retry cao hơn.
Use case 2: SLO/SLA thực dụng
SLO hay gặp: 95% request < 200ms hoặc 99% < 500ms. Với hệ thống yêu cầu rất cao, đôi khi sẽ có mục tiêu dạng 99.9% < X.
Percentile biến thành cam kết chất lượng:
- p95: cam kết cho majority
- p99: kiểm soát tail
- p99.9: kiểm soát extreme tail
Use case 3: CI/CD & DevOps flow (build/test/deploy time)
Không chỉ latency HTTP. Percentile dùng tốt cho:
- p90 build time, ví dụ 90% build xong trong 12 phút
- p95 deploy lead time, ví dụ hầu hết deploy không vượt 20 phút
Điểm hay: nó giúp tìm sporadic slowdown (cache miss, cold runner, dependency fetch chậm…). Với CI/CD, p99.9 thường ít dùng hơn vì cần rất nhiều mẫu và giá trị thực tiễn không phải lúc nào cũng cao.
Use case 4: Batch/job processing
- p95 runtime: majority job ổn
- p99 runtime: tail jobs kéo dài, dễ làm vỡ deadline/backlog tăng
- p99.9 (nếu job cực nhiều và cần kiểm soát extreme tail): bắt các job cực kỳ hiếm nhưng cực kỳ lâu
Cách benchmark percentile như thế nào (thực tế hay sai ở đây)?
Đủ mẫu cho percentile bạn quan tâm
p99 nghĩa là xét 1% chậm nhất nên nếu bạn chỉ chạy ít request, con số này sẽ dao động mạnh. p99.9 còn khó hơn vì nó xét 0.1% chậm nhất nên cần rất nhiều samples (hoặc nhiều lần chạy) thì mới đáng tin.
Tách giai đoạn khởi động
Hệ thống thường có giai đoạn đầu: warm cache, warm connection, autoscale… Nếu trộn vào kết quả, percentile sẽ bị méo. Thực hành hay dùng:
- Chạy một đoạn warm-up
- Chỉ lấy số liệu trong đoạn steady-state
Chọn kiểu tạo tải phù hợp
Nếu bạn giữ cố định số người gọi cùng lúc (concurrency cố định), khi hệ thống chậm nó sẽ tự giảm tốc độ gọi. Đây là hiệu ứng closed-loop load generation (dễ làm latency nhìn đẹp hơn). Nếu bạn giữ cố định số request đến mỗi giây (RPS cố định), rõ ràng nó sẽ phản ánh thật hơn khi traffic đến đều (gần với open-loop).
Không trộn nhiều loại request vào chung
Đừng gộp nhiều endpoint/payload khác nhau vào cùng một p95 rồi kết luận. Benchmark nên tách theo endpoint, loại request, cache hit/miss (nếu có).
Tránh lấy percentile của percentile
Thêm cái sai hay gặp nữa là tính p95 theo từng phút, rồi lại lấy p95 của các p95 đó. Kết quả rất dễ lệch. Tốt nhất là tính percentile từ dữ liệu gốc (hoặc histogram chuẩn) trong đúng khoảng thời gian benchmark.
Nên nhìn bộ percentile nào?
Một bộ hay dùng khi benchmark service:
- p50: median latency
- p90/p95: high-percentile latency cho majority traffic
- p99: tail latency
- p99.9: extreme tail latency (khi hệ thống rất nhạy)
Mẫu report benchmark thực tế
Khi benchmark, report tốt thường có:
Bối cảnh
- Version, config, commit, loại máy/cluster, vùng đặt máy
- Dữ liệu lớn cỡ nào, cache đang nóng hay lạnh
- Tool tạo tải và chạy ở đâu
Cách chạy
- Tải đến theo kiểu nào (giữ RPS hay giữ concurrency)
- Tăng tải thế nào, chạy ổn định bao lâu
Kết quả
- Throughput + error rate + retries
- p50/p90/p95/p99 (và p99.9 nếu cần) (tách theo endpoint)
- CPU/mem/GC, DB pool, queue depth… (để giải thích)
Kết luận
- Chậm do xử lý lâu hay do phải đợi
- Thay đổi nào gây khác biệt (DB, cache, network…)
Case study thực tế
Latency budget và cách đọc p95/p99 theo budget
Thay vì chỉ nói p95 = bao nhiêu ms, hãy đặt mục tiêu dạng:
- p95 < X ms
- p99 < Y ms
- p99.9 < Z ms (nếu cần)
Và đi kèm câu giải thích 1 dòng, ví dụ: Trong 10,000 requests, khoảng 100 requests sẽ tệ hơn p99, khoảng 10 requests sẽ tệ hơn p99.9.
Nguyên tắc kiềng ba chân
Kết quả benchmark nên luôn trình bày theo cụm:
- Throughput (RPS)
- Error rate (timeout/5xx)
- p50/p95/p99 (hoặc thêm p99.9)
Chọn percentile theo loại hệ thống (cực thực dụng)
- Web/API thông thường: p50 + p95 + p99
- User-facing cực nhạy (payment, realtime, trading): thêm p99.9
- Batch/worker: p95 + p99 (p50 ít quan trọng hơn)
- CI/CD: p90/p95 là đủ, p99.9 thường không cần
Golden signals để giải thích tại sao p99 xấu
Nếu p99/p99.9 xấu, 90% trường hợp thủ phạm rơi vào 1 trong các nhóm này:
- Saturation: CPU throttling, thread pool/connection pool cạn
- Downstream: DB/cache/external API chậm
- Queueing: backlog/queue depth tăng
- GC/Memory pressure
- Network: RTT/loss tăng
Kết luận nhanh benchmark
- p50 ổn, p95 ổn, p99 xấu: Phần lớn request ổn, nhưng đuôi latency tệ (do GC pause, lock contention, resource contention, hoặc downstream thỉnh thoảng chậm).
- p95 tăng theo load, throughput không tăng tương ứng: Hệ thống bắt đầu vào vùng bão hoà (saturation) — queueing tăng, throughput không tăng do hạn chế tài nguyên.
- Latency đẹp nhưng error/retry tăng: Kết quả benchmark không đáng tin — latency trông đẹp có thể do fail nhanh hoặc client retry làm sai bức tranh.
Checklist mini để tránh benchmark sai
- Warm-up tách riêng
- Không trộn nhiều endpoint vào 1 percentile
- Cùng load profile và cùng dataset
- Luôn báo cáo retry + timeout
- p99.9 chỉ dùng khi có đủ samples
Cũng hết ruột gan rồi
Tôi đi làm lúc 5y exp mới bắt đầu có các task chính thức về benchmark hệ thống, và đến giờ cũng may mắn được qua khá nhiều bài toán. Nhưng mà có thể các bạn trẻ hơn làm trong các doanh nghiệp lớn hơn đã tiếp xúc bài toán này từ lúc còn 2-3-4 năm kinh nghiệm chẳng hạn. Có gì cần thiết, hữu ích tôi cũng đã chia sẻ rồi, cũng vì lĩnh ngộ tư tưởng các bác và các sếp tại DevOps VietNam để cùng lan toả giá trị phát triển cộng đồng. Mọi người làm thực tế có vấn đề gì cần trao đổi cứ bình luận nhé.
Tags: Benchmark, p50, p70, p80, p90, p95, p99, p99.9, Percentile