많은 서버리스 가이드나 Supabase 문서에서 poolclass=pool.NullPool 설정을 권장하곤 한다. 이 말은 마치 "미들웨어(Supavisor)가 모든 풀 관리를 대신해 주니, 클라이언트 레벨의 풀은 꺼두는 것이 정답이다"라는 오해를 불러일으키기 쉽다. 하지만 이는 성능을 위한 선택이 아니라 안전을 위한 조치에 가깝다. NullPool을 사용하는 가장 큰 이유는 서버리스 함수는 실행 후 즉시 소멸하지 않고 'Warm' 상태로 대기할 수 있기 때문이다. 이때 클라이언트 풀링이 켜져 있으면 DB와의 연결을 지속하며 비싼 DB 자원을 수 분간 낭비한다.

미들웨어 레벨의 풀링이 유독 Postgres 생태계에서 강조되는 이유는 Postgres의 작동 방식과도 연관이 있다. Postgres는 연결이 맺어질 때마다 새로운 프로세스를 만드는데 스레드를 만드는 방식에 비해 무겁고 생성 속도가 느리다. 수백 개의 인스턴스가 동시에 뜰 때, 이들의 요청을 받아들여 실제 DB에는 감당 가능한 수준의 연결만 전달하는 '방파제' 역할이 필요하다. 그 역할을 미들웨어 레벨의 풀러가 수행하고 있다고 볼 수 있다.

그래서 본질적으로 미들웨어에서 커넥션 풀을 관리해 주더라도, DB 클라이언트가 미들웨어와 연결을 하는 시간의 최적화 문제는 그대로 남아 있다. 따라서 대부분의 애플리케이션에는 직접 구현했든 DAL을 사용했든 클라이언트 레벨의 커넥션 풀이 필요하다.


parse me : 언젠가 이 메모에 쓰이면 좋을 것 같은 재료들입니다.

  1. None

from : 이 메모에 쓰인 생각을 만든 과거의 생각들과 연관관계를 설명합니다.

  1. 커넥션 풀은 여러 계층에 존재할 수 있다. 애플리케이션 레벨(SQLAlchemy)도 있고, Postgres의 경우에는 미들웨어 레벨 풀링(PgBouncer)도 있다.
  2. 데이터베이스 응답은 빠른 속도가 중요하므로, 연결을 끊어버리면 매번 TCP 핸드셰이크와 DB 핸드셰이크를 다시 해야 한다는 문제가 있다. 그래서 전송 계층으로 HTTP이 상태 유지가 기본인 TCP 프로토콜에 의존하고, 커넥션 풀을 이용해 한 번 맺어둔 TCP 연결을 재사용한다.

supplementary : 이 메모에 작성된 생각을 뒷받침하는 새로운 메모입니다.

  1. None

opposite : 이 메모에 작성된 생각과 대조되는 새로운 메모입니다.

  1. None

to : 이 메모에 작성된 생각으로부터 발전된 생각의 메모입니다.

  1. None