Triệu chứng gây nhầm: p99 5–20s, error timeout, CPU 15%, “chắc cần
scale pod”. Thực ra request đang xếp hàng
acquire connection — pool 10, handler concurrency 200.
Đây là inventory hẹp ở tầng DB (hoặc Redis, HTTP client pool) — không phải thiếu CPU.
Demo: pool nhỏ · chờ acquire · CPU “rảnh”.
Nhận mặt
- Latency cao + CPU thấp + load average không tương xứng.
- Metric: pool wait time, active=max, pending acquires.
- DB phía server: sessions thấp hơn app “concurrent requests”.
- Trace: span “pool.acquire” dài, query span ngắn phía sau.
Nguyên nhân thường
- Pool size << in-flight handlers.
- Query chậm / missing index giữ connection lâu.
- Leak: mượn không trả (hiếm hơn nhưng có).
- Retry chồng thêm acquire trong khi bản cũ còn giữ connection (không cancel).
- Transaction dài ôm connection qua await HTTP (anti-pattern).
Align ba số
app_handler_concurrency ≤ sum(db_pool_per_instance) × instances
≤ db.max_connections − headroom (admin, migrate)
Ví dụ: 4 pod × pool 15 = 60 → DB max_connections ≥ 60 + 10
Handler concurrency 50/pod × 4 = 200 ≫ 60 → 140 request chờ acquire
Hướng xử lý
- Align ba số trên (đừng chỉ tăng một đầu).
- Acquire timeout fail-fast — đừng chờ 30s im lặng.
- Statement timeout; cancel khi budget hết.
- Tối ưu query trước khi “tăng pool mù” (DB cũng có trần).
- Bulkhead pool theo use-case nếu một path nuốt hết slot.
Một câu
Chậm + CPU rảnh → nghi pool/lock, đừng chỉ scale CPU.
Đếm active / wait — không đoán.