← 전체 글로 돌아가기

DB

PostgreSQL 연결 수가 늘어날 때 Prisma 인스턴스를 먼저 의심한 회고

개발 서버를 저장할 때마다 PostgreSQL 연결이 늘었다. 쿼리보다 PrismaClient 생성 위치를 바꿔 해결한 회고.

쿼리가 느린 줄 알았다

개발 중인 Next.js 앱에서 몇 번 저장하고 나면 PostgreSQL이 “too many clients”를 냈다. 목록 쿼리가 문제라고 보고 인덱스부터 살폈지만, pg_stat_activity에는 비슷한 연결이 계속 쌓여 있었다. 개발 모드의 hot reload 때마다 new PrismaClient()가 실행된 것이었다.

연결 수부터 확인했다

데이터베이스에서 애플리케이션 이름과 상태를 확인하니 원인이 선명해졌다.

SELECT state, count(*)
FROM pg_stat_activity
WHERE datname = current_database()
GROUP BY state;

개발 환경에서만 재현된다는 점이 힌트였다. 서버리스 환경과 장기 실행 서버도 연결 전략이 다르므로, 한 가지 코드를 모든 환경의 정답처럼 두면 안 된다.

개발 중에는 인스턴스를 재사용했다

PrismaClient를 모듈마다 만들지 않고 전역 캐시에 하나만 보관했다.

import { PrismaClient } from '@prisma/client';

const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient };

export const prisma = globalForPrisma.prisma ?? new PrismaClient();

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;

이후에는 모든 쿼리에서 이 prisma만 import했다. disconnect()를 요청마다 호출하는 방식도 시도했지만, 연결을 계속 열고 닫아 오히려 동작을 읽기 어려웠다.

회고: 숫자를 보고 고쳤다

연결 제한을 크게 올리면 당장은 조용해질 수 있다. 하지만 왜 연결이 생겼는지는 가려진다. 앞으로는 DB 오류를 만나면 쿼리 시간, 활성 연결 수, 클라이언트 생성 위치를 한 묶음으로 확인할 생각이다. 개발 환경에서만 나는 문제도 운영 전에 고칠 수 있다.