HikariCP 풀 크기 계산기

실제로 잴 수 있는 숫자 — 초당 요청 수, 요청이 커넥션을 잡는 시간, 스레드 구조, DB 의 max_connections — 로 maximum-pool-size를 정합니다. 풀 크기를 실제로 묶는 세 가지 한계(부하, 교착 방지, 배포 중 DB 한도)를 함께 따져 권장값과 YAML 설정을 보여 줍니다.

브라우저에서만 동작 · 업데이트 · 작성 Srue, 백엔드 개발자 · View in English

부하 (앱 인스턴스 1대 기준)
건/초
ms
%
스레드
개
개
DB 한도
개
개
대
대
개

권장 maximum-pool-size

7

인스턴스당 · 3대 합계 커넥션 21개

이 숫자가 나온 과정

부하 기준 (리틀의 법칙 + 여유분)
7
교착 방지 최소값
1
인스턴스당 DB 한도 (배포 중 포함)
35
DB 권장치: (코어 × 2) + 스핀들, 전체
17

롤링 배포까지 고려해도 DB 한도 안에 들어옵니다.

application.yml

spring:
  datasource:
    hikari:
      maximum-pool-size: 7
      # minimum-idle: 비워 두기 — HikariCP 는 고정 크기 풀을 권장
      connection-timeout: 3000     # 기본 30초 대신 빨리 실패하게
      max-lifetime: 1800000        # DB·프록시의 유휴 타임아웃보다 짧게

풀 크기를 정하는 세 가지 숫자

  1. 부하. 리틀의 법칙에 따라 동시에 쓰이는 커넥션 수는 초당 요청 수 × 커넥션 점유 시간입니다. 초당 200건이 각각 25ms 씩 잡으면 평균 5개가 쓰입니다.
  2. 교착 방지. 스레드 하나가 커넥션을 둘 잡을 수 있으면(열린 트랜잭션 안의 REQUIRES_NEW 등) 풀이 Tn × (Cm − 1) + 1보다 작을 때 모든 스레드가 하나씩 쥔 채 두 번째를 기다리며 멈출 수 있습니다.
  3. DB 한도. 모든 인스턴스가 하나의 max_connections를 나눠 씁니다. 관리용·복제·배치 몫을 남기고, 롤링 배포 중 더 뜨는 파드까지 셈해야 합니다.

계산 예시

계산기 기본값 — 인스턴스당 초당 200건, 점유 25ms, 여유 30%, 인스턴스 3대 + 배포 중 1대, DB max_connections 151개 중 10개 예약 — 로 계산하면:

HikariCP 풀 크기 계산 예시
항목계산결과
부하 기준200 × 0.025초 × 1.37
교착 방지 최소값스레드당 커넥션 1개1
인스턴스당 DB 한도(151 − 10) ÷ (3 + 1)35
DB 권장치 (전체)코어 8 × 2 + 117
권장값max(부하, 교착), DB 한도 안에서7

인스턴스당 7개는 기본값 10보다 작아 보이지만, 요청이 커넥션을 빨리 돌려주기 때문에 충분합니다. 50개가 필요하다면 고칠 곳은 대개 풀이 아니라 트랜잭션입니다.

풀을 키우기 전에 볼 것

  • 트랜잭션 안의 외부 호출. @Transactional 안에서 HTTP 를 호출하면 응답이 올 때까지 커넥션을 잡고 있습니다. 트랜잭션 밖으로 빼면 필요한 풀 크기도 같이 줄어듭니다.
  • Open Session in View. spring.jpa.open-in-view는 기본으로 켜져 있어 화면 렌더링까지 커넥션을 잡습니다. 끄기만 해도 점유 시간이 크게 줄어드는 경우가 많습니다.
  • 느린 쿼리. 4ms 걸릴 쿼리가 400ms 걸리면 같은 트래픽에 커넥션이 100배 필요합니다. DB 를 키우는 것보다 인덱스가 쌉니다.

자주 묻는 질문

Spring Boot 의 HikariCP 기본 풀 크기는 얼마인가요?

maximumPoolSize 기본값은 10이고 minimumIdle 도 같은 값이라, 인스턴스마다 커넥션 10개짜리 고정 풀이 됩니다. Spring Boot 는 이 기본값을 바꾸지 않으므로 spring.datasource.hikari.maximum-pool-size 로 직접 정합니다.

“Connection is not available, request timed out after 30000ms”는 무슨 뜻인가요?

connectionTimeout(기본 30초) 동안 풀의 모든 커넥션이 사용 중이라 요청이 포기한 것입니다. 흔한 원인은 @Transactional 안의 외부 호출이나 느린 쿼리처럼 커넥션을 오래 잡는 코드, 커넥션 누수, 실제로 부족한 풀 크기입니다. 풀을 키우기 전에 hikaricp.connections.usage 와 pending 지표부터 보세요.

minimum-idle 을 maximum-pool-size 와 같게 둬야 하나요?

HikariCP 는 minimumIdle 을 설정하지 않고 고정 크기 풀로 쓰기를 권장합니다. 트래픽이 몰리는 순간에 새 커넥션을 여는 지연을 피할 수 있습니다.

풀 크기는 앱 전체 기준인가요, 인스턴스 기준인가요?

인스턴스 기준입니다. 서버 10대에 maximum-pool-size 20이면 최대 200개를 엽니다. 롤링 배포 중에는 옛 파드와 새 파드가 겹치므로, DB max_connections 를 동시에 떠 있을 수 있는 인스턴스 수로 나눠서 정해야 합니다.

가상 스레드를 쓰면 달라지나요?

spring.threads.virtual.enabled=true 면 요청 스레드 수가 사실상 무제한이라 풀이 실제 동시성 한계가 됩니다. 요청이 Tomcat 이 아니라 getConnection() 에서 줄을 섭니다. 풀은 DB 기준으로 잡고, connection-timeout 을 낮춰 빨리 실패하게 하고, pending 지표를 지켜보세요.