PostgREST 호환성에 대한 기사에서는 서버가 기능적으로 다루는 것(필터, 임베딩, RPC, RLS)과 서버가 사용자에게 맡긴 사항을 자세히 설명합니다. 이것은 다른 곳에서 나온 것입니다. Aurabase 코드와 공식 PostgREST 문서를 소스로 사용하여 PostgREST가 실제로 규모가 정체되는 위치와 이유를 문서화합니다. 우리는 우리가 직접 운영하지 않은 로드 뱅크를 여기서 재생산하는 것이 아닙니다. 우리의 벤치마크 방법론인는 공개된 프로토콜 없이 고립된 수치가 우리에게 신뢰할 수 없는 것처럼 보이는 이유를 설명합니다.
필수사항
- PostgREST 자체는 가볍습니다. CPU는 50
250밀리코어, 전용 Aurabase 인스턴스의 복제본당 RAM은 64128MB입니다. 원시 HTTP 처리량은 프로덕션에서 제한 요소가 되는 경우가 거의 없습니다. - 실제 상한선은 Postgres 연결 예산:
PGRST_DB_POOL× 복제본입니다. Aurabase 코드에서 확인됨: 전용 레벨(10×2)에서 프로젝트당 20개 연결, 공유 레벨(2×2)에서 4개. 이는 동일한max_connections에 더 많은 테넌트를 수용하기 위한 의도적인 선택입니다. Prefer: count=exact는 대형 테이블에서 값비싼 MVCC 스캐닝을 강제합니다. PostgREST는count=planned및count=estimated라는 두 가지 저렴한 대안을 문서화하며 대략적인 비용이 듭니다.db-max-rows한도(Aurabase에서는 기본적으로 1000줄)는Content-Range에 보고하지 않고 응답을 자릅니다(실제 조건에서 측정, 아래 자세히 설명).- DDL 마이그레이션 후 PostgREST 스키마 캐시는 비동기적으로 다시 로드됩니다. Aurabase 게이트웨이는 포기하기 전에 최대 8회(최악의 경우 누적 약 3.5초)를 재시도합니다. 이 동작은 코드에 직접 문서화되어 있습니다.
PostgREST 벤치마크가 측정하는 것과 측정하지 않는 것
PostgREST의 HTTP 처리량 테스트는 주로 Postgres를 측정하며 PostgREST는 거의 측정하지 않습니다. 서버는 베이스 앞에 있는 얇은 번역 레이어입니다. 실제 로드의 대부분에서 응답 시간은 SQL 쿼리를 생성한 프로세스가 아니라 실행된 SQL 쿼리에 의해 좌우됩니다.
PostgREST 프로젝트는 GitHub에서 이 주제에 대한 전용 저장소인 PostgREST/postgrest-benchmark를 유지 관리합니다. 이 저장소는 격리된 마케팅 수치를 게시하는 대신 릴리스 간 처리량 변화를 추적합니다. 우리는 여기서 그것을 수행하거나 재출판한 적이 없습니다. 결과는 하드웨어, 회로도 크기 및 테스트된 시나리오에 따라 달라지며, 그림을 인용하기 전에 자체 벤치마크 프로토콜이 문서화해야 하는 변수와 정확히 일치합니다.
PostgREST 아래에는 실제로 중요한 계층, 즉 동시 로드 시 SQL 트랜잭션 시간을 측정하는 pgbench이 있습니다. 이것은 공식 PostgreSQL 벤치마크 도구입니다(postgresql.org/docs/current/pgbench.html, 2026년 8월 24일 액세스). 이 문서에서는 이 프로토콜을 여기서 재현하는 대신 프로덕션에서 PostgREST의 네 가지 구체적인 아키텍처 제한 사항을 설명합니다. 각 제한 사항은 Aurabase 소스 코드 또는 공식 프로젝트 문서에서 확인됩니다.
Aurabase에서 PostgREST 인스턴스의 실제 공간
각 Aurabase Postgres 엔진 프로젝트는 해당 클러스터와 함께 배치된 2개의 전용 PostgREST 복제본을 받습니다. 이를 배포하는 Kubernetes 매니페스트는 적절한 리소스를 설정합니다.
이러한 복제본이 실제로 소비하는 것은 CPU가 아니라 Postgres 기본에 대한 연결입니다. 각 PostgREST 인스턴스는 테넌트에 배포된 PgBouncer 풀러를 통하지 않고 기본(-rw)에 직접 연결됩니다. 이 선택은 이미 PostgREST 호환성에 대한 기사에 자세히 설명되어 있습니다. LISTEN/NOTIFY 스키마 다시 로드 메커니즘에는 트랜잭션 모드의 풀러와 호환되지 않는 지속적인 연결이 필요합니다. 이 기사에서 추가하는 내용: 연결 측면에서 실제 비용은 얼마이며 최고점은 어디입니까?
복제본당 이 풀의 크기(PGRST_DB_POOL)는 각 프로젝트에 대해 PostgREST 매니페스트를 빌드하는 함수인 k8s_tenant.rs에서 확인된 프로젝트 수준에 따라 의도적으로 다릅니다.
| 베어링 | PGRST_DB_POOL/복제본 | 복제본 | 연결 / 각성 프로젝트 |
|---|---|---|---|
| 전용(프리미엄, A1) | 10(PostgREST 기본값) | 2 | 20 |
| 공유(제품군, 무료/프로/팀) | 2(Aurabase 기본값, 낮아짐) | 2 | 4 |
전용 수준에서는 제약 조건이 완화됩니다. 프로젝트에는 자체 CNPG 클러스터가 있으므로 자체 max_connections가 있으므로 여유 이웃이 없습니다. 공유 수준에서는 동일한 조직의 여러 프로젝트가 단일 클러스터를 공유합니다. 바로 이러한 맥락에서 연결 예산이 결정되며 다음 섹션에서 개발됩니다.
연결 예산은 동시에 실행되는 테넌트 수를 결정합니다.
공유 Postgres 클러스터에서 동시에 활성화되는 프로젝트 수를 제한하는 것은 HTTP 처리량이 아닙니다. 이는 사용 가능한 max_connections와 비교하여 PostgREST 인스턴스가 기본에서 열려 있는 연결 수입니다.
Aurabase는 fleet.rs: (max_connections − réserve superuser/CNPG − connexions réservées au pooler) ÷ connexions par projet éveillé에서 확인된 실제 클러스터 제한에서 직접 이 예산을 도출합니다. 바닥은 1입니다. 고정 예약은 10개의 연결입니다(수퍼유저, CNPG 인스턴스 관리자, 메트릭 내보내기, 프로비저너 관리 마진). 전달된 결함(복제본당 2개의 풀, 2개의 복제본 또는 활성화된 프로젝트당 4개의 연결)에 대해 계산에서는 클러스터의 크기 수준에 따라 세 가지 다른 예산을 제공합니다.
출처: fleet.rs::derive_wake_budget 및 wake_budget_for_org_plan, Aurabase 코드에서 파생됨, 2026년 8월 24일에 다시 읽음.
This budget is not a quota of owned projects: an team organization can hold 50 projects, most of which are dormant. This is a cap of concurrency: the number of projects that can hold open connections at the same time on the primary. A wake-up over budget does not fail, it is deferred until a sibling project goes back to sleep, checked in the same file. The topic of sizing max_connections itself is expanded upon in our article on tuning of max_connections, and the dedicated/mutualized tradeoff as a whole in dedicated vs. shared base.
선호하는 이유: count=exact는 큰 테이블에서 쿼리 속도를 저하시킵니다.
정확한 총계를 요청하면 Postgres는 각 쿼리와 함께 필터링된 결과의 표시되는 행 수를 계산하게 됩니다. 이는 무료 작업이 아니라 테이블과 함께 증가하는 비용입니다.
PostgreSQL은 기본적으로 인덱싱된 행 카운터를 유지하지 않습니다. MVCC에서 행의 가시성은 행을 읽는 트랜잭션에 따라 달라집니다. 따라서 정확한 COUNT(*)는 미리 계산된 값을 읽는 대신 후보 행을 방문해야 합니다. 이는 자체 대략적인 카운터를 Postgres 트랜잭션 동작과 비교하는 ClickHouse와 같은 분석 공급업체를 포함하여 Postgres 생태계에서 잘 문서화되어 있는 구조적 제한 사항입니다.
PostgREST는 이러한 세 가지 계산 전략을 기본적으로 문서화합니다(postgrest.org, 2026년 8월 24일 액세스). exact 전략은 스캔 가격으로 총액을 보장합니다. planned는 쿼리 플래너에서 거의 무료 추정치를 반환합니다. estimated는 임계값에 따라 둘 사이를 자동으로 전환합니다. 선택은 미용적이지 않습니다. 수백만 행의 테이블에 count=exact을 요구하는 페이지 매김은 사용자가 마지막 페이지를 참조하지 않더라도 각 페이지에서 이 스캔에 대한 비용을 지불합니다.
count=exact가 없으면 db-max-rows 잘림이 표시되지 않습니다.
행 캡은 정확한 합계를 명시적으로 요청하지 않는 한 본문이나 헤더에 표시 없이 PostgREST 응답을 자를 수 있습니다. 가정이 아닌 전용 Aurabase 인스턴스의 실제 조건에서 측정했습니다.
PGRST_DB_MAX_ROWS=5이 있는 10행 테스트 테이블에서 PostgREST v12.2.3은 매우 다른 두 가지 상황에 대해 정확히 동일한 Content-Range 헤더를 렌더링합니다.
| 쿼리 | 렌더링된 선 | 콘텐츠 범위 | 메타(Aurabase) |
|---|---|---|---|
| ?limit=50 (카운트 제외) | 5/10 진짜 | 0-4/* | {} |
| ?한계=50&개수=정확함 | 5/10 진짜 | 0-4/10 | {총계: 10} |
count=exact없이 5개 행의 응답은 실제로 5개만 포함하는 테이블과 구별할 수 없습니다. Content-Range: 0-4/*는 렌더링된 행을 설명하며 제한은 적용되지 않습니다. 이 경우 실제 적용되는 한도는 어디에도 나타나지 않으며 Aurabase SDK의 PostgREST 경로에서 직접 측정됩니다.
PostgREST 배포가 db-max-rows(Aurabase 기본값은 1000)를 설정하는 경우 전체 페이지를 감지하기 위해 data.length을 요청된 제한과 비교하는 클라이언트가 잘못되었을 수 있습니다. 서버 한도가 이 제한보다 낮아지면 즉시 오류가 나타납니다. 신뢰할 수 있는 유일한 신호는 수신된 라인 수를 count=exact에서 반환된 total와 비교하는 것입니다. 이는 이전 섹션에서 설명한 비용 절충을 직접적으로 구현합니다.
마이그레이션 후 스키마 캐시 다시 로드
PostgREST는 시작 시 Postgres 스키마를 메모리에 유지합니다. DDL(테이블 생성, 열 추가) 후에는 새 경로가 응답하기 전에 이 캐시를 다시 로드해야 하며 이 다시 로드는 비동기식입니다.
이 창에 도달하는 쓰기는 테이블이 실제로 Postgres 측에 존재하더라도 일시적인 404(캐시가 아직 최신 상태가 아님)를 수신할 수 있습니다. Aurabase 게이트웨이는 postgrest_proxy.rs에서 확인된 제한된 재시도 루프를 통해 이를 흡수합니다. 최대 8회 시도, 백오프 증가(시도당 250ms + 100ms), 최악의 경우 누적 시간은 3.5초입니다. 이 메커니즘은 쓰기에만 영향을 미치고 읽기에는 영향을 미치지 않습니다.
게이트웨이는 다시 로드 신호를 내보내지 않고 대기만 합니다. 유일한 실제 트리거는 DDL 경로의 데이터베이스 서비스에서 발행한 pg_notify('pgrst', 'reload schema')입니다. 마이그레이션 경로가 이 신호를 내보내는 것을 잊어버린 경우 8번의 시도는 절대 변경되지 않는 캐시에서 소진을 시도합니다. 이 위험은 위장되지 않고 코드 주석에 문서화되어 있습니다.
자체 호스팅 PostgREST 배포의 경우 교훈이 일반화됩니다. 애플리케이션의 각 DDL 경로는 NOTIFY 또는 SIGUSR1 신호를 통해 프로세스에 대한 다시 로드를 트리거해야 합니다. 그렇지 않으면 마이그레이션으로 인해 배포 직후 간헐적인 오류로 위장된 p99 대기 시간 스파이크가 발생합니다.
원시 처리량이 아니라 아키텍처가 분할하는 것
여기에 문서화된 네 가지 제한 사항에는 한 가지 공통점이 있습니다. 격리된 HTTP 처리량 테스트에서는 아무 것도 나타나지 않지만 네 가지 모두 PostgREST 배포가 프로덕션으로 확장되는지 여부를 결정합니다.
- 연결 예산: 테넌트당 처리량에 관계없이 공유 클러스터에서 동시에 활성화된 테넌트 수를 제한합니다.
- 정확한 COUNT의 비용: 로드가 아닌 테이블과 함께 증가합니다.
planned/estimated으로 우회됩니다. - 자동 잘림: 올바르게 구성된 행 캡은 여전히 잘못 계측된 페이징을 깨뜨릴 수 있습니다.
- 스키마 다시 로드: 각 마이그레이션 후 대기 시간 창으로, 다시 로드 신호가 제대로 연결되어 있으면 제한되고, 그렇지 않으면 무제한입니다.
자체 호스팅 PostgREST, Hasura 스타일 GraphQL 레이어 또는 사용자 정의 API 중에서 선택하든 이 4개 축은 격리된 req/s 수치보다 더 나은 비교 지점입니다. PostgREST 대 Hasura 대 사용자 정의 API비교를 참조하세요. 데이터베이스 앞에 있는 풀러의 선택도 그만큼 중요합니다. PgBouncer vs Supavisor vs PgCat 비교에서는 PostgREST가 트랜잭션 모드에서 풀러를 통과할 수 없는 이유를 자세히 설명합니다.
자주 묻는 질문
기억해야 할 것
PostgREST는 HTTP 로드만으로는 거의 중단되지 않습니다. 그러기에는 아키텍처가 너무 단순합니다. 생산이 중단되는 것은 그것을 둘러싼 것입니다. 복제본이 열려 있는 연결 수, 정확한 총 비용은 얼마입니까? 여기에는 잘린 부분이 계속 표시되는지 여부와 마이그레이션 후 기간이 지속되는 기간도 포함됩니다.
이러한 네 가지 제한 사항은 Aurabase에만 국한되지 않고 자체 호스팅 또는 관리형 PostgREST 배포에 적용됩니다. 이 코드가 보여주는 것은 다중 테넌트 배포가 프로덕션에서 이를 놀라운 상태로 두지 않고 명시적으로 만드는 방법입니다.