본문으로 건너뛰기

6.4 호환성과 제약 목록

Neon은 "그냥 PostgreSQL"이라는 약속과 "저장 계층을 바꿨다"는 사실 사이에 있습니다. SQL과 wire protocol은 그대로입니다. 반면 파일 시스템과 superuser에 의존하던 기능은 달라집니다. WAL을 직접 다루는 도구도 달라집니다. 이 장은 도입 검토에서 확인해야 할 제약을 범주별로 모았습니다. 각 항목은 2026년 9월 공식 문서를 기준으로 합니다. 확장 목록처럼 자주 바뀌는 항목은 문서 링크를 정본으로 둡니다.

버전과 업그레이드

지원 버전은 PostgreSQL 14, 15, 16, 17, 18입니다. 최신 minor는 문서 기준으로 14.24, 15.19, 16.15, 17.11, 18.6입니다. PostgreSQL 커뮤니티의 5년 지원 정책에 따라 EOL에 도달하면 지원이 끝납니다.

In-place major version upgrade는 제공되지 않습니다. 새 버전으로 옮기려면 원하는 버전의 project를 새로 만들고 데이터를 옮깁니다. 문서는 pg_dump/pg_restore와 logical replication(Neon-to-Neon)을 안내합니다. Branch가 많은 project에서는 branch 트리까지 함께 옮길 방법이 없습니다. 따라서 업그레이드 시점을 branch 정리 시점에 맞춰 계획합니다.

Superuser와 파일 시스템

PostgreSQL superuser 대신 neon_superuser 역할이 제공됩니다. 콘솔, CLI, API로 만든 역할은 이 멤버십을 받지만 SQL의 CREATE ROLE로 만든 역할은 받지 않습니다. neon_superuser로 할 수 없는 대표 작업은 다음과 같습니다.

  • 지원 목록에 없는 확장 설치
  • CREATE TABLESPACE (오류 반환)
  • 호스트 OS와 파일 시스템 접근, COPY ... TO PROGRAM
  • track_commit_timestamp 활성화 (플랫폼 제약으로 미지원)

Unlogged table은 compute 로컬 디스크에 저장되므로 compute를 재시작하면 사라집니다. Vanilla에서는 crash 후에만 비워집니다. Neon에서는 scale to zero 후에도 비워집니다. 따라서 "임시 캐시 테이블" 용도라도 재생성 로직이 필요합니다. Temporary table은 세션 수명 동안 로컬 디스크를 사용합니다. 한도는 20 GiB와 15 GiB × 최대 compute 크기 중 큰 값입니다. 문서는 "whichever is highest"라고 적고 있으므로 큰 compute를 쓰면 한도도 함께 올라갑니다.

확장

CREATE EXTENSION으로 설치하는 방식은 같지만 설치 가능한 목록은 고정되어 있습니다. 대표 지원 확장과 미지원 예시는 다음과 같습니다.

구분확장비고
지원pgvector 0.8.x버전은 PostgreSQL major에 따라 다름
지원postgis 3.3~3.6관련 확장 포함
지원timescaledb 2.10~2.24Apache-2 기능만, compression 미지원
지원pg_stat_statements 1.9~1.12
지원pg_cron 1.6명시적 활성화 필요, compute가 켜진 동안만 job 실행
지원pg_partman 5.1.0
Deprecatedplv8PG14~16 3.1.10, PG17 3.2.3, PG18 미지원. 보안 사유로 신규 설치 차단
Deprecatedpg_search신규 project 제공 중단. 기존 설치는 2026-09-21까지 마이그레이션
미지원sslinfoproxy가 SSL을 종단하므로 무의미
미지원file_fdwscale to zero 시 파일 접근 불가

Deprecated와 미지원은 다릅니다. plv8은 확장 목록에 남아 있어 기존에 설치한 project에서는 계속 보이지만 새로 설치하는 경로가 막혀 있습니다. pg_search는 신규 project에서 아예 제공되지 않고 기존 설치도 기한 안에 다른 전문 검색 방식으로 옮겨야 합니다. 반면 sslinfofile_fdw는 플랫폼 구조상 제공되지 않는다고 문서가 명시한 항목입니다.

새 확장은 Neon 지원팀 또는 Discord로 요청합니다. pg_mooncake, pgrag 같은 실험 확장은 SET neon.allow_unstable_extensions = 'true' 후 설치합니다. 운영 project에는 권장되지 않습니다. 전체 목록은 Supported Postgres extensions 문서가 정본입니다.

pg_cron의 "compute가 켜진 동안만 실행" 조건은 scale to zero와 충돌합니다. 새벽 3시 배치를 pg_cron에 등록합니다. 그 시각에 compute가 scale to zero 상태이면 배치가 실행되지 않습니다. 배치는 외부 스케줄러에서 연결을 열어 실행하거나 scale to zero를 끕니다.

WAL 포맷과 외부 도구

Compute는 패치된 PostgreSQL입니다. Heap WAL record에는 t_cid 필드가 추가되었습니다. core_changes 문서는 이 변경으로 WAL 포맷이 vanilla와 호환되지 않는다고 명시합니다. 이 사실에서 다음 내용을 추론할 수 있습니다. 다만 공식 문서가 각 내용을 개별적으로 확인하지는 않았으므로 조건부로 봅니다.

  • Vanilla PostgreSQL을 Neon compute의 physical standby로 붙이는 구성은 동작하지 않을 가능성이 높습니다. 실제로 Neon은 physical replication 대신 read replica(같은 pageserver를 읽는 compute)와 logical replication을 제공합니다.
  • pg_waldump 같은 vanilla WAL 도구로 Neon WAL을 해석하려면 Neon 빌드의 도구가 필요합니다.
  • Compute 안의 pg_basebackup, pg_receivewal은 사용자의 접근 대상이 아닙니다. 백업은 branch와 instant restore로 대체됩니다. 외부 반출은 pg_dump와 logical replication으로 대체됩니다.

Logical replication은 publisher와 subscriber 모두 지원합니다. Project 단위로 활성화하며 한 번 켜면 되돌릴 수 없습니다. 활성화하면 wal_levellogical로 바뀝니다. 이 기능은 외부 PostgreSQL로 데이터를 내보내는 경로를 제공합니다. 따라서 lock-in 우려를 상당 부분 줄입니다.

연결 수와 pooling

max_connections는 compute 크기에 따라 자동으로 정해집니다. 문서의 공식은 두 단계입니다.

compute_size = min(max_compute_size, 8 × min_compute_size)
max_connections = max(100, min(4000, floor(compute_size × 419.66)))
compute_size (CU)max_connections
0.25104
1419
2839
41,678
83,357
10 이상4,000 (상한)

첫 줄이 중요합니다. Autoscaling에서 기준이 되는 compute_size는 최대 크기 그 자체가 아니라 "최소 크기의 8배"로 한 번 더 제한됩니다. 0.25~2 CU 범위라면 min(2, 8 × 0.25)가 2이므로 839입니다. 그런데 0.25~16 CU 범위로 넓혀도 min(16, 2)가 2가 되어 max_connections는 그대로 839입니다. 연결 수를 늘리려면 최대 크기만 올리는 것으로는 부족하고 최소 크기를 함께 올려야 합니다. 더 많은 클라이언트 연결이 필요하면 엔드포인트 호스트명에 -pooler를 붙여 PgBouncer를 경유합니다. Pooler는 transaction mode로 동작하며 최대 10,000 클라이언트 연결을 받습니다. user와 database 조합마다 default_pool_size = 0.9 × max_connections 크기의 pool을 둡니다.

Transaction mode의 제약은 PgBouncer 일반 제약과 같습니다. 세션 변수 SET/RESET, LISTEN/NOTIFY, SQL 수준 PREPARE/DEALLOCATE, 세션에 걸친 temporary table은 동작하지 않거나 예상과 다르게 작동합니다. 드라이버의 protocol-level prepared statement는 지원됩니다.

Scale to zero가 일어나면 유휴 연결이 끊깁니다. 이때 세션 상태(파라미터, prepared statement, LISTEN 등록)도 사라집니다. 세션 상태에 의존하는 애플리케이션은 유료 플랜에서 scale to zero를 끕니다.

Branch와 project 한도

항목FreeLaunchScale
포함 branch 수/project101025
포함량 초과 시생성 실패$1.50/branch-month (시간 비례)$1.50/branch-month (시간 비례)
Root branch (schema-only 포함)3525
Schema-only branch 저장0.5 GB (project 공유)3 GB20 GB
Read replica/project3문서 확인 필요문서 확인 필요

표의 10과 25는 최대 생성 개수가 아니라 요금에 포함된 동시 branch 수입니다. Free 플랜에서는 이 값이 곧 생성 한도이므로 11번째 branch 생성이 실패합니다. 유료 플랜에서는 생성이 막히지 않고 초과분이 시간 비례로 과금됩니다. CI에서 branch를 자동 생성하는 파이프라인은 이 차이 때문에 Free와 유료 플랜에서 실패 양상이 다릅니다. 한쪽은 오류로 드러나고 다른 한쪽은 청구서로 드러납니다.

Schema-only branch는 부모와 연결되지 않은 독립 root branch입니다. 따라서 reset --parent를 지원하지 않으며 root branch 한도를 소비합니다. 리전은 project 생성 시 정해지며 이후 변경할 수 없습니다. 다른 리전으로 옮기려면 새 project와 logical replication을 사용합니다.

Neon 고유 파라미터

Compute의 postgresql.conf에는 vanilla에 없는 neon.* 파라미터가 들어갑니다. Part III의 compute spec 파일에서 확인한 항목입니다.

파라미터역할
neon.tenant_idcompute가 속한 tenant
neon.timeline_idcompute가 읽고 쓰는 timeline (branch)
neon.pageserver_connstringGetPage 요청을 보낼 pageserver 주소
neon.safekeepersWAL을 push할 safekeeper 목록
max_replication_write_lagbackpressure 한도

Neon 클라우드에서는 사용자가 이 값을 바꾸지 않습니다. 파라미터는 콘솔과 API에서 변경합니다. ALTER SYSTEM의 허용 범위는 문서에서 확인해야 합니다. synchronous_standby_nameswalproposer로 고정되어 있는 점도 확인해야 합니다. Vanilla에서 동기 standby 이름을 넣는 자리에는 Neon의 WAL proposer가 들어갑니다. 이 값을 바꾸면 commit 내구성 모델이 깨집니다.

제약을 확인하는 순서

도입을 검토할 때 다음 순서로 확인하면 제약을 뒤늦게 발견할 가능성이 줄어듭니다.

  1. 현재 사용 중인 확장 목록을 \dx로 조회해 지원 표와 대조합니다.
  2. superuser 권한이 필요한 스크립트(COPY TO PROGRAM, tablespace, ALTER SYSTEM)를 찾습니다.
  3. pg_cron, unlogged table, 세션 변수 의존 코드가 scale to zero와 충돌하는지 확인합니다.
  4. 최대 동시 연결 수를 목표 CU의 max_connections와 비교하고 pooler 사용 여부를 정합니다.
  5. Physical standby나 WAL 아카이브에 의존하는 백업 절차를 branch와 logical replication으로 대체할 수 있는지 검토합니다.

연습 문제

  1. 운영 DB에서 SELECT extname, extversion FROM pg_extension;을 실행해 Neon 지원 목록과 대조합니다.
  2. Part III 환경에서 CREATE TABLESPACECREATE UNLOGGED TABLE을 실행하고 compute 재시작 후 결과를 확인합니다.
  3. Pooler 연결로 SET search_path를 실행한 뒤 다음 트랜잭션에서 값이 유지되는지 확인합니다.

심화 체크

  • Major upgrade 절차를 branch 정리 계획과 함께 세웠는가?
  • 세션 상태 의존 코드를 찾아 scale to zero 정책과 맞췄는가?
  • 외부 반출 경로(logical replication, pg_dump)를 실제로 한 번 실행해 보았는가?

참고