실무에서 DB Connection Pool Size는 어떻게 정해야 할까?
백엔드 서버를 운영하다 보면 Thread Pool만큼 자주 고민하게 되는 값이 있다.
바로 DB Connection Pool Size다.
Java/Spring 환경에서는 보통 HikariCP를 많이 사용하고, 설정은 대략 이런 형태다.
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.connection-timeout=3000
처음 보면 단순해 보인다.
“DB 커넥션을 몇 개까지 열어둘 것인가?”
하지만 실무에서는 이 값을 감으로 정하면 위험하다.
DB 커넥션 풀 크기는 애플리케이션 처리량, DB 서버 리소스, 쿼리 성능, 트랜잭션 길이, API 응답 시간, 장애 전파 범위까지 직접적으로 영향을 준다.
이 글에서는 Spring Boot에서 많이 사용하는 HikariCP를 기준으로 설명한다.
다만 원리는 Java뿐 아니라 Node.js, Python, Go, .NET 등 다른 언어나 DB 라이브러리에서도 동일하게 적용된다.
1. DB Connection Pool이 필요한 이유
애플리케이션이 DB에 접근할 때마다 매번 새로운 연결을 만들면 비용이 크다.
DB 연결에는 TCP 연결, 인증, 세션 생성 등의 비용이 들어간다.
그래서 커넥션 풀은 미리 DB 연결을 만들어두고 재사용한다.
흐름은 대략 이렇다.
1. 애플리케이션이 DB 작업을 시작한다.
2. Connection Pool에서 사용 가능한 Connection을 빌린다.
3. SQL을 실행한다.
4. 트랜잭션을 종료한다.
5. Connection을 Pool에 반환한다.
즉, 커넥션 풀은 DB 연결을 무한히 만드는 구조가 아니다.
DB Connection Pool = 제한된 DB 연결 자원을 재사용하는 장치
중요한 점은 커넥션을 “사용한다”는 말이 단순히 쿼리 실행 시간만 의미하지 않는다는 것이다.
트랜잭션이 열려 있는 동안 커넥션은 계속 점유된다.
@Transactional
public void processOrder(OrderRequest request) {
Order order = orderRepository.save(request.toEntity());
paymentClient.pay(request); // 외부 API 호출
order.complete();
}
위 코드에서 주의할 점은 @Transactional 안에서 외부 API를 호출한다는 것이다.
이 경우 DB 작업이 끝났더라도 트랜잭션이 끝나지 않았기 때문에 커넥션이 반환되지 않을 수 있다.
즉, 외부 API 응답을 기다리는 동안 DB 커넥션을 붙잡고 있을 수 있다.
이런 코드가 많으면 커넥션 풀을 아무리 크게 잡아도 금방 고갈된다.
2. 라이브러리마다 기본 Connection Pool Size가 다른 이유
커넥션 풀을 보다 보면 라이브러리마다 기본값이 다르다.
예를 들어 어떤 라이브러리는 기본 최대 커넥션 수가 10개이고, 어떤 라이브러리는 5개 또는 100개처럼 보일 수 있다.
또 어떤 환경은 별도 설정을 하지 않으면 커넥션 풀을 적극적으로 사용하지 않거나, 런타임/드라이버/프레임워크 조합에 따라 동작이 다르다.
이 기본값이 다른 이유는 단순히 “어떤 값이 정답이기 때문”이 아니다.
라이브러리마다 다음 전제가 다르기 때문이다.
- 주 사용 환경이 웹 서버인지, 배치인지, CLI인지
- 동시 요청 모델이 스레드 기반인지, 이벤트 루프 기반인지
- DB 커넥션 생성 비용을 얼마나 크게 보는지
- 안전한 기본값을 우선하는지, 처리량을 우선하는지
- DB 서버에 과도한 연결을 만들지 않도록 보수적으로 잡는지
- 사용자가 명시적으로 튜닝하길 기대하는지
예를 들어 Spring MVC + HikariCP는 스레드 기반 서버에서 많이 사용된다.
요청 스레드가 DB 커넥션을 빌려 SQL을 실행하고 반환하는 구조가 일반적이다.
반면 Node.js는 이벤트 루프 기반이고, DB 드라이버나 ORM마다 풀 동작 방식이 다르다.
Go의 database/sql은 SetMaxOpenConns, SetMaxIdleConns로 동시 열린 커넥션 수와 idle 커넥션 수를 직접 제한한다.
즉, 기본값은 라이브러리 설계자가 생각한 “안전한 출발점”일 뿐이다.
실무에서는 기본값을 그대로 믿기보다 다음 기준으로 다시 산정해야 한다.
- 서비스 TPS
- 요청당 DB 커넥션 점유 시간
- DB 서버 max_connections
- 애플리케이션 인스턴스 수
- DB CPU/메모리/Lock 상태
- Thread Pool 크기
- Slow Query 여부
결국 중요한 것은 특정 라이브러리의 default 값이 아니라, 우리 서비스가 DB에 동시에 얼마만큼의 부하를 허용할 것인가다.
3. DB Connection Pool Size를 크게 잡으면 좋은가?
직관적으로는 이렇게 생각하기 쉽다.
“커넥션을 많이 열어두면 동시에 더 많은 요청을 처리할 수 있지 않을까?”
일부는 맞지만 항상 맞지는 않다.
커넥션 풀을 너무 작게 잡으면 애플리케이션 스레드들이 커넥션을 기다리게 된다.
Request Thread
↓
Connection Pool에서 대기
↓
connection-timeout 초과
↓
SQLTransientConnectionException
반대로 커넥션 풀을 너무 크게 잡으면 DB 서버가 감당해야 할 동시 쿼리 수가 늘어난다.
그 결과 다음 문제가 발생할 수 있다.
- DB CPU 사용률 증가
- Lock 경합 증가
- Disk I/O 증가
- Buffer cache 효율 저하
- Context switching 증가
- 쿼리 응답 시간 증가
- 전체 처리량 저하
즉, DB 커넥션 풀은 크면 클수록 좋은 값이 아니다.
커넥션 풀 크기는 애플리케이션이 DB에 줄 수 있는 최대 동시 부하량이다.
maximumPoolSize = 이 애플리케이션 인스턴스가 DB에 동시에 걸 수 있는 최대 압력
따라서 커넥션 풀 크기를 정한다는 것은 단순히 애플리케이션 설정을 정하는 것이 아니라, DB 서버에 허용할 동시 부하량을 정하는 일이다.
4. HikariCP의 핵심 설정
Spring Boot에서 자주 사용하는 Hikari 설정은 다음과 같다.
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
maximumPoolSize
풀에서 관리할 수 있는 최대 커넥션 수다.
spring.datasource.hikari.maximum-pool-size=30
애플리케이션 인스턴스 하나가 DB에 동시에 최대 30개의 커넥션을 사용할 수 있다는 의미다.
서버 인스턴스가 여러 대라면 전체 DB 커넥션 수는 곱해진다.
애플리케이션 인스턴스 4대
각 인스턴스 maximumPoolSize 30
전체 최대 DB 커넥션 수 = 4 × 30 = 120
이 부분을 놓치면 운영에서 문제가 생긴다.
로컬에서는 문제가 없었는데 운영에서 인스턴스를 늘린 뒤 DB 커넥션이 고갈되는 경우가 있다.
minimumIdle
풀에서 유지하려는 최소 유휴 커넥션 수다.
spring.datasource.hikari.minimum-idle=10
트래픽이 갑자기 들어왔을 때 매번 커넥션을 새로 만들지 않도록 일정 수의 유휴 커넥션을 유지한다.
다만 HikariCP에서는 특별한 이유가 없다면 minimumIdle을 생략하고 maximumPoolSize와 동일하게 고정 풀처럼 운영하는 방식도 많이 사용한다.
중요한 것은 minimumIdle을 너무 크게 잡으면 유휴 상태에서도 DB 커넥션을 많이 점유한다는 것이다.
connectionTimeout
커넥션 풀에서 커넥션을 빌릴 때 최대 대기 시간이다.
spring.datasource.hikari.connection-timeout=3000
3초 안에 커넥션을 얻지 못하면 예외가 발생한다.
이 값은 장애 대응에서 매우 중요하다.
너무 길면 요청 스레드가 오래 묶이고, 장애가 늦게 드러난다.
너무 짧으면 순간적인 트래픽 피크에도 실패가 많이 발생할 수 있다.
실무에서는 보통 2~5초 정도에서 시작하는 경우가 많다.
실시간성이 중요한 서비스라면 더 짧게 잡을 수도 있다.
maxLifetime
커넥션의 최대 생존 시간이다.
spring.datasource.hikari.max-lifetime=1800000
DB나 네트워크 장비가 오래된 idle connection을 먼저 끊어버리는 경우가 있다.
그래서 애플리케이션 쪽에서 일정 시간 이후 커넥션을 교체하도록 설정한다.
중요한 점은 DB 서버의 connection timeout보다 Hikari의 maxLifetime을 짧게 잡는 것이 안전하다는 것이다.
5. DB Connection Pool Size 공식
Thread Pool과 마찬가지로 DB Connection Pool도 참고할 수 있는 공식이 있다.
실무적으로는 다음 기준이 유용하다.
필요 커넥션 수 ≈ 초당 요청 수 × 요청당 DB 커넥션 점유 시간
조금 더 표현하면:
Connection Pool Size ≈ TPS × DB Connection Hold Time
여기서 중요한 것은 단순 쿼리 시간이 아니라 커넥션 점유 시간이다.
예를 들어 다음과 같은 API가 있다고 하자.
초당 요청 수: 100 TPS
요청당 DB 커넥션 점유 시간: 50ms
계산은 다음과 같다.
100 × 0.05초 = 5
이론적으로 이 API만 보면 동시에 필요한 커넥션은 약 5개다.
여기에 피크 트래픽, 쿼리 지연, 트랜잭션 변동성을 고려해 여유를 둔다.
기본 필요량 5개
여유 계수 2~3배
권장 시작값: 10~15개
반대로 요청당 커넥션 점유 시간이 길어지면 필요한 커넥션 수는 급격히 늘어난다.
초당 요청 수: 100 TPS
요청당 DB 커넥션 점유 시간: 300ms
100 × 0.3초 = 30
이 경우 같은 100 TPS라도 필요한 커넥션 수는 30개가 된다.
즉, 커넥션 풀 크기를 늘리기 전에 봐야 할 것은 다음이다.
요청량이 많은가?
아니면 커넥션을 오래 잡고 있는가?
대부분의 경우 문제는 커넥션 수가 부족한 것이 아니라, 커넥션을 너무 오래 잡고 있는 코드에 있다.
6. 커넥션 점유 시간은 어떻게 측정할까?
처음부터 정확히 알기는 어렵다.
그래서 실무에서는 모니터링과 부하 테스트로 측정한다.
Spring/Hikari 환경에서는 다음 지표를 본다.
hikaricp.connections.active
hikaricp.connections.idle
hikaricp.connections.pending
hikaricp.connections.timeout
hikaricp.connections.usage
hikaricp.connections.acquire
hikaricp.connections.creation
특히 중요한 지표는 다음이다.
active connections
현재 사용 중인 커넥션 수다.
active가 maximumPoolSize에 자주 붙어 있다
→ 커넥션 풀이 부족하거나 DB 작업이 오래 걸린다
pending threads
커넥션을 얻기 위해 기다리는 스레드 수다.
pending이 증가한다
→ 애플리케이션 스레드가 DB 커넥션을 기다리고 있다
connection acquire time
커넥션을 빌리는 데 걸린 시간이다.
acquire time 증가
→ 커넥션 풀 대기가 발생한다
connection usage time
커넥션을 빌린 뒤 반환하기까지의 시간이다.
usage time 증가
→ 커넥션을 오래 잡고 있다
이 값이 커넥션 풀 튜닝에서 특히 중요하다.
단순 SQL 실행 시간이 20ms인데 connection usage time이 500ms라면, 애플리케이션 코드에서 트랜잭션을 길게 잡고 있을 가능성이 있다.
7. 부하 테스트로 산정하는 절차
실무에서는 다음 순서로 접근하는 것이 좋다.
1. 현재 API의 DB 사용 구간을 파악한다.
2. 쿼리 시간과 트랜잭션 시간을 측정한다.
3. Hikari active/pending/usage/acquire 지표를 수집한다.
4. 목표 TPS 기준으로 필요한 커넥션 수를 계산한다.
5. 부하 테스트를 수행한다.
6. p95/p99 응답 시간, DB CPU, active connection, pending thread를 확인한다.
7. 커넥션 풀 크기와 쿼리/트랜잭션 구조를 함께 조정한다.
예를 들어 부하 테스트 결과가 다음과 같다고 하자.
목표 TPS: 300
평균 connection usage time: 40ms
p95 connection usage time: 80ms
평균 기준으로 계산하면:
300 × 0.04 = 12
p95 기준으로 계산하면:
300 × 0.08 = 24
이 경우 maximumPoolSize=20~30 정도를 출발점으로 볼 수 있다.
하지만 DB CPU가 이미 80~90%라면 커넥션을 더 늘리는 것은 위험하다.
커넥션을 늘리면 동시 쿼리 수가 증가해 DB가 더 느려질 수 있다.
8. 커넥션 풀을 늘려야 하는 경우
다음 조건이 함께 보이면 커넥션 풀 증가를 검토할 수 있다.
- DB CPU는 여유가 있다.
- 쿼리 자체는 빠르다.
- connection acquire time이 증가한다.
- pending thread가 증가한다.
- active connection이 maximumPoolSize에 자주 도달한다.
- 애플리케이션 응답 지연이 커넥션 대기에서 발생한다.
예를 들어:
DB CPU: 40%
DB slow query 없음
Hikari active: 항상 max 근처
Hikari pending: 증가
connection acquire p95: 500ms
connection usage p95: 30ms
이 경우는 커넥션을 빨리 쓰고 반환하고 있는데, 풀 크기가 작아 대기가 생기는 상황일 수 있다.
이때는 maximumPoolSize를 늘리는 것이 도움이 될 수 있다.
9. 커넥션 풀을 늘리면 안 되는 경우
반대로 다음 상황에서는 커넥션 풀을 늘리면 문제가 악화될 수 있다.
- DB CPU가 이미 높다.
- Slow query가 많다.
- Lock wait가 많다.
- connection usage time이 길다.
- 트랜잭션이 길다.
- 외부 API 호출이 트랜잭션 안에 있다.
- active connection이 높고 DB 응답 시간이 같이 느려진다.
예를 들어:
DB CPU: 90%
Hikari active: max 근처
Hikari pending: 증가
connection usage p95: 2초
slow query 증가
lock wait 증가
이 상황에서 커넥션 풀을 늘리면 DB에 더 많은 동시 쿼리가 몰린다.
결과적으로:
DB 부하 증가
쿼리 응답 시간 증가
커넥션 점유 시간 증가
active connection 증가
pending thread 증가
악순환이 생긴다.
이때는 커넥션 풀을 늘리는 것이 아니라 다음을 봐야 한다.
- 쿼리 튜닝
- 인덱스 점검
- 트랜잭션 범위 축소
- 외부 API 호출을 트랜잭션 밖으로 분리
- 배치 처리
- 캐싱
- 읽기/쓰기 분리
- DB scale-up 또는 scale-out
10. Thread Pool과 Connection Pool은 같이 봐야 한다
Thread Pool과 DB Connection Pool은 따로 튜닝하면 안 된다.
예를 들어 다음 설정을 보자.
spring.datasource.hikari.maximum-pool-size=20
그런데 Async Executor는 이렇게 되어 있다.
executor.setCorePoolSize(30);
executor.setMaxPoolSize(100);
이 Executor 안에서 대부분 DB 작업을 한다면 어떻게 될까?
동시 worker thread: 최대 100개
DB connection: 최대 20개
20개는 DB 작업 수행
80개는 커넥션 대기
이 구조는 좋은 병렬 처리가 아니다.
대기 스레드가 늘어났을 뿐이다.
따라서 DB 작업을 수행하는 Thread Pool의 크기는 DB Connection Pool과 함께 맞춰야 한다.
DB 중심 Executor maxPoolSize <= DB connection pool size
더 정확히는 특정 Executor가 전체 DB 커넥션을 독점하지 않게 해야 한다.
전체 Hikari maximumPoolSize = 30
일반 API 요청용 여유: 15~20
Async DB 작업용 max: 5~10
Batch 작업용 max: 3~5
이렇게 나누는 것이 더 안전하다.
11. 애플리케이션 인스턴스 수까지 고려해야 한다
커넥션 풀 설정에서 가장 많이 놓치는 것이 인스턴스 수다.
예를 들어 운영 환경이 다음과 같다고 하자.
WAS 인스턴스 6대
각 인스턴스 Hikari maximumPoolSize = 30
그러면 DB 입장에서 최대 커넥션 수는 다음과 같다.
6 × 30 = 180
DB의 max_connections가 200이라고 해보자.
여기에 DBA 접속, 배치 서버, 모니터링, 다른 서비스 커넥션까지 들어오면 금방 한계에 도달할 수 있다.
따라서 커넥션 풀은 인스턴스 하나만 보지 말고 전체 시스템 기준으로 계산해야 한다.
전체 DB 허용 커넥션 수
- 운영/관리용 여유
- 다른 서비스 사용량
- 배치 사용량
- 모니터링 사용량
= 현재 서비스가 사용할 수 있는 커넥션 예산
그리고 이 예산을 인스턴스 수로 나눈다.
서비스에 허용된 전체 커넥션 수: 120
WAS 인스턴스 수: 6
인스턴스당 maximumPoolSize = 120 / 6 = 20
즉, 인스턴스를 늘릴 때는 Hikari maximumPoolSize를 그대로 두면 전체 DB 커넥션 압력이 증가한다.
12. 읽기/쓰기 분리 환경에서는 Pool도 분리해서 봐야 한다
Read Replica를 사용하거나 Master/Replica 구조를 사용하는 경우에는 커넥션 풀도 분리해서 봐야 한다.
writeDataSource
- INSERT
- UPDATE
- DELETE
- 트랜잭션 처리
readDataSource
- SELECT
- 조회 API
- 통계 조회
각 풀의 크기는 다르게 잡을 수 있다.
예를 들어 쓰기 DB는 부하가 민감하고 lock 영향이 크기 때문에 보수적으로 잡고, 읽기 DB는 replica 수와 조회량에 따라 별도로 산정한다.
write.hikari.maximum-pool-size=20
read.hikari.maximum-pool-size=50
하지만 읽기 풀도 무작정 크게 잡으면 replica DB가 느려질 수 있다.
읽기/쓰기 분리에서도 원칙은 같다.
Connection Pool Size = DB에 허용할 동시 부하량
13. Long Transaction이 커넥션 풀을 고갈시킨다
커넥션 풀 장애의 상당수는 단순히 커넥션 수가 부족해서가 아니라 커넥션을 오래 잡고 있어서 발생한다.
대표적인 패턴은 다음과 같다.
트랜잭션 안에서 외부 API 호출
@Transactional
public void approve(Long id) {
Order order = orderRepository.findById(id).orElseThrow();
externalPaymentClient.approve(order); // 외부 API 호출
order.approve();
}
외부 API가 2초 걸리면 그동안 DB 커넥션도 같이 점유될 수 있다.
개선 방향은 외부 API 호출을 트랜잭션 밖으로 분리하는 것이다.
public void approve(Long id) {
Order order = orderReader.get(id);
externalPaymentClient.approve(order);
orderApprovalService.approveInTransaction(id);
}
@Transactional
public void approveInTransaction(Long id) {
Order order = orderRepository.findById(id).orElseThrow();
order.approve();
}
대량 처리 트랜잭션
@Transactional
public void bulkProcess(List<Item> items) {
for (Item item : items) {
repository.save(item);
}
}
대량 작업을 하나의 트랜잭션으로 묶으면 커넥션 점유 시간이 길어진다.
개선 방향은 chunk 단위로 나누는 것이다.
10만 건 한 번에 처리
→ 1000건씩 chunk 처리
Open Session In View
Spring Boot에서 OSIV가 켜져 있으면 View 렌더링 시점까지 영속성 컨텍스트가 유지될 수 있다.
API 서버에서는 보통 OSIV를 끄는 방향을 선호한다.
spring.jpa.open-in-view=false
OSIV를 끄면 Lazy Loading 문제가 드러날 수 있지만, 트랜잭션 경계를 명확히 하는 데 도움이 된다.
14. 실무적인 시작값
정답은 없지만, 실무에서 출발점으로 사용할 수 있는 기준은 있다.
작은 서비스 또는 내부 시스템
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=3000
일반적인 Spring Boot API 서버
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.connection-timeout=3000
트래픽이 있는 API 서버
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.connection-timeout=3000
읽기 트래픽이 많고 DB가 충분히 받쳐주는 경우
spring.datasource.hikari.maximum-pool-size=40~50
spring.datasource.hikari.minimum-idle=10~20
spring.datasource.hikari.connection-timeout=3000
단, 이 값들은 어디까지나 출발점이다.
다음 조건을 반드시 함께 봐야 한다.
- WAS 인스턴스 수
- DB max_connections
- DB CPU
- slow query
- lock wait
- connection usage time
- connection acquire time
- pending thread
- p95/p99 API latency
15. 다른 언어와 라이브러리에서도 원리는 같다
HikariCP는 Java/Spring에서 많이 쓰는 구현체일 뿐이다.
다른 환경에서도 본질은 같다.
Node.js
- mysql2 pool
- pg pool
- TypeORM pool
Python
- SQLAlchemy QueuePool
- Django DB connection management
Go
- database/sql SetMaxOpenConns
- SetMaxIdleConns
- SetConnMaxLifetime
.NET
- ADO.NET connection pooling
라이브러리마다 기본 커넥션 풀 개수와 기본 동작은 다를 수 있다.
하지만 봐야 할 지표는 거의 같다.
- 최대 열린 커넥션 수
- 유휴 커넥션 수
- 커넥션 획득 대기 시간
- 커넥션 점유 시간
- 커넥션 생존 시간
- DB 서버의 최대 연결 수
- 애플리케이션 인스턴스 수
예를 들어 Go에서는 다음과 같이 설정한다.
db.SetMaxOpenConns(30)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime(time.Minute * 30)
Java Hikari의 maximumPoolSize와 Go의 SetMaxOpenConns는 비슷한 역할을 한다.
즉, 언어와 라이브러리가 달라도 원칙은 같다.
커넥션 풀 크기는 애플리케이션이 DB에 동시에 줄 수 있는 부하량을 제한하는 값이다.
16. 체크리스트
DB Connection Pool Size를 정할 때 다음 질문을 확인한다.
1. DB 서버의 max_connections는 얼마인가?
2. 현재 서비스가 사용할 수 있는 전체 커넥션 예산은 얼마인가?
3. WAS 인스턴스는 몇 대인가?
4. 인스턴스당 maximumPoolSize는 얼마인가?
5. API 요청당 DB 커넥션 점유 시간은 얼마인가?
6. 트랜잭션 안에서 외부 API를 호출하고 있지는 않은가?
7. Slow query나 lock wait가 있는가?
8. Hikari active가 max에 자주 붙는가?
9. pending thread가 증가하는가?
10. connection acquire time이 증가하는가?
11. connection usage time이 긴가?
12. DB CPU는 여유가 있는가?
13. Thread Pool 크기가 DB Pool보다 과도하게 크지는 않은가?
14. 인스턴스를 늘릴 때 전체 커넥션 수도 같이 증가하는가?
15. 라이브러리의 기본값을 그대로 사용하고 있지는 않은가?
이 질문에 답하지 않고 커넥션 풀 크기만 늘리는 것은 위험하다.
17. 결론
DB Connection Pool Size는 크게 잡는다고 무조건 성능이 좋아지는 값이 아니다.
작게 잡으면 애플리케이션 스레드가 커넥션을 기다리고,
크게 잡으면 DB 서버에 과도한 동시 부하가 걸릴 수 있다.
또한 라이브러리마다 기본 커넥션 풀 개수가 다를 수 있지만, 그것은 각 라이브러리의 설계 철학과 사용 환경이 다르기 때문이다.
기본값은 안전한 출발점일 뿐, 우리 서비스에 맞는 정답은 아니다.
핵심 원칙은 다음과 같다.
Connection Pool Size는 DB에 허용할 동시 부하량이다.
필요 커넥션 수는
TPS × Connection 점유 시간
으로 근사할 수 있다.
하지만 최종값은
DB max_connections,
WAS 인스턴스 수,
DB CPU,
Slow Query,
Lock Wait,
Hikari active/pending/usage/acquire 지표,
p95/p99 응답 시간
을 보고 정해야 한다.
Thread Pool과 마찬가지로 DB Connection Pool도 정답 공식이 있는 것이 아니다.
공식은 초기값을 잡기 위한 기준이고,
최종 설정은 부하 테스트와 운영 모니터링을 통해 결정해야 한다.
내가 실무에서 가장 중요하게 보는 기준은 이것이다.
커넥션 풀을 늘리기 전에, 커넥션을 오래 잡고 있는 코드가 있는지 먼저 확인해야 한다.
커넥션 풀 크기 튜닝의 본질은 숫자를 크게 만드는 것이 아니라,
DB 커넥션이라는 제한된 자원을 짧게 사용하고 빠르게 반환하도록 시스템을 설계하는 것이다.
'나의 주니어 개발 일기 > 트러블슈팅' 카테고리의 다른 글
| Thread Pool Size를 CPU 코어 수 × 2로 잡으면 될까? (1) | 2026.07.06 |
|---|---|
| 주변 지오펜스 조회 성능 개선 (like 주변 맛집 검색) (0) | 2026.06.25 |
| 로컬 LLM 기반 AI Code Reviewer 구축기 - 단순 코드 리뷰를 넘어 아키텍처 리뷰까지 (0) | 2026.06.11 |
| PolyCARP를 활용한 드론 Geofence/Area 공간 판단 구현기 - 좌표계, 경계선 그리고 수많은 삽질들 (0) | 2026.06.04 |
| 드론 안전 제어 시스템을 설계하며 고민했던 것들 (0) | 2026.06.04 |
