Vì tổng kết nối tới database là số instance × kích thước pool mỗi instance. Pool 20 với 4 instance là 80 kết nối; với 40 instance thành 800, vượt xa max_connections mặc định của PostgreSQL (100).
Đây là cái bẫy cố hữu khi scale ngang: cấu hình cục bộ không đổi nhưng tổng thể vượt trần. Tăng max_connections không phải lời giải tốt — mỗi kết nối PostgreSQL là một backend process tốn bộ nhớ, và quá nhiều kết nối đồng thời làm thông lượng giảm vì tranh chấp và context switch, chứ không tăng.
Xử lý:
- Giảm pool mỗi instance và tính ngược từ trần DB: đặt trần tổng trước, chia cho số instance tối đa. Pool nhỏ mà DB khoẻ thường nhanh hơn pool lớn mà DB nghẹt.
- Thêm connection pooler ở giữa (PgBouncer, ProxySQL, RDS Proxy): hàng trăm client dùng chung một nhóm nhỏ kết nối thật. Chế độ transaction pooling ghép hiệu quả nhất nhưng cấm dùng session state như prepared statement toàn cục hay SET ở mức session.
- Rút ngắn thời gian giữ kết nối: không mở transaction rồi gọi API ngoài bên trong; đặt statement_timeout để một query treo không giữ kết nối vô hạn.
- Tách pool theo loại tải: pool riêng cho job nền, tránh job nặng chiếm hết kết nối của luồng phục vụ người dùng.
Dấu hiệu nhận biết ở tầng app: lỗi timeout khi lấy kết nối từ pool (khác với timeout query) — nghĩa là request đang xếp hàng chờ pool chứ không phải DB chạy chậm.