Thông báo đó chỉ nói pool cạn, không nói vì sao. Ba nguyên nhân, phân biệt trước rồi mới chỉnh cấu hình:
1. Connection leak — code lấy connection mà không trả (dùng EntityManager thủ công, @Transactional bọc một lời gọi HTTP chậm bên trong). Bật cờ này để Hikari log stack trace của chỗ giữ connection quá lâu:
spring.datasource.hikari.leak-detection-threshold=200002. Truy vấn chậm — vài truy vấn thiếu index chiếm connection hàng chục giây. Xem pg_stat_activity / slow query log; sửa truy vấn, đừng tăng pool.
3. Pool thật sự quá nhỏ so với lượng request đồng thời — trường hợp duy nhất nên tăng maximumPoolSize.
Đặt maximumPoolSize bao nhiêu: công thức tham chiếu của HikariCP là connections = (core_count * 2) + effective_spindle_count, tính theo core của máy DB, không phải máy app. Con số thực tế thường nhỏ hơn nhiều so với trực giác — một DB 4 core rơi vào khoảng 10 connection.
Hai điều cần nhớ khi trả lời:
- Pool lớn hơn không nhanh hơn. Vượt quá khả năng song song của DB thì các connection chỉ tranh CPU/disk của nhau, latency tăng. Pool nhỏ với hàng đợi thường cho throughput tốt hơn.
- Tính tổng theo cụm. 10 pod × maximumPoolSize=20 là 200 connection tới DB; phải chia ngân sách max_connections cho số instance, và cân nhắc một pooler như PgBouncer khi số instance lớn.
Hikari khuyến nghị pool cố định: để minimumIdle bằng maximumPoolSize thay vì co giãn.