PostgreSQL의 대체 스토리지 엔진 생태계를 살펴보고, 힙 대체, 컬럼형 TAM, 레이크하우스 기반 TAM, 도메인 특화 TAM의 설계 선택과 한계를 정리합니다.

PostgreSQL 12는 2019년 10월에 테이블 액세스 메서드 API를 도입했고, 커뮤니티는 그 다음 6년 동안 이것으로 무엇을 할 수 있을지 탐색했다. 초기의 예상은 몇 번의 릴리스만 지나면 플러그형 스토리지 엔진의 번성하는 생태계가 생길 것이라는 것이었다. 분석용 컬럼형, OLTP용 언두 로그, 고온 워크로드용 인메모리 엔진이 등장하고, 힙은 “기본값일 뿐, 유일한 선택지는 아닌” 상태가 될 것이라는 전망이었다.
실제로는 거의 그렇게 되었다. 생태계는 존재한다. 그리고 프로젝트 역사상 어느 때보다 신뢰할 만한 선택지가 많다는 의미에서는 분명히 활발하다. 동시에 초기에 그려졌던 비전이 암시한 것보다 더 혼란스럽고, 예상보다 몇 가지 설계 철학 주변으로 더 집중되어 있으며, 자금이 끊기거나 API 자체의 벽에 부딪혀 멈춘 프로젝트들의 잔해도 널려 있다. 이 시리즈의 다음 글에서 이 모든 것에 숫자를 붙이기 전에, 실제로 무엇이 나와 있는지, 각 프로젝트가 무엇을 하려는지, 그리고 아키텍처상의 단층선이 어디를 가로지르는지 정리해 둘 필요가 있다.
이 글은 그 현황 조사다. 벤치마크는 나중에 다룬다.
PostgreSQL의 대체 스토리지 엔진을 이해할 때 가장 먼저 알아야 할 점은, 테이블 액세스 메서드 API가 진정한 의미의 플러그형 스토리지 계층은 아니라는 것이다. 이것은 힙을 중심으로 설계된 인터페이스를 부분적으로 일반화한 결과물이며, 튜플 형태의 추상화다. TableAmRoutine에는 38개의 콜백이 있다. 몇몇은 필수이고 예상한 대로 동작한다(scan_begin, tuple_insert, tuple_delete, index_fetch_tuple). 하지만 많은 콜백은 블록 번호와 오프셋으로 구성된 튜플 식별자가 있다고 가정하는데, 스토리지가 페이지 형태라면 괜찮지만 그렇지 않다면 문제가 된다.
TAM API는 인덱스까지 확장되지도 않는다. 인덱스 액세스 메서드는 tableam보다 훨씬 오래전부터 존재한 별도의 플러그인 지점이며, 둘은 TID 가정으로 결합되어 있다. 튜플을 식별하는 방식으로 (blocknum, offset) 외의 것을 쓰는 컬럼형 엔진을 만들고 싶다면, 인덱스 AM을 속일 수 있을 정도로 TID를 흉내 내거나, 정직한 TID를 가진 그림자 행 저장소를 유지해야 한다. 대부분의 진지한 컬럼형 TAM은 후자를 택한다. 이것은 선택 가능한 엔지니어링이 아니라, 추상화가 부과하는 제약이다.
그 결과 오늘날 PostgreSQL에서 “대체 스토리지 엔진”이란 대체로 다음 네 가지 중 하나를 뜻한다.
각 범주는 존재 이유도 다르고 실패하는 방식도 다르다.
OrioleDB는 이 영역에서 현재 살아 있는 프로젝트 중 아키텍처적으로 가장 야심차며, 힙을 정면으로 겨냥하는 유일한 프로젝트다. MVCC 모델은 언두 로그 기반이다. 오래된 튜플 버전이 주 힙에 쌓이는 대신 언두 체인으로 밀려나기 때문에, 설계상 기본 저장소에는 블로트가 없다. 그 대신 가비지 컬렉션 문제는 언두 보존 문제로 바뀐다. 이것은 다른 실패 양상을 가진 다른 문제지만, 중요한 점은 PostgreSQL 운영자들이 지난 30년 동안 VACUUM 일정을 맞추며 씨름해 온 바로 그 문제는 아니라는 것이다.
OrioleDB는 또한 행 수준 WAL이 있는 copy-on-write 체크포인트, “squizzled pointers”를 사용하는 인메모리 캐싱 계층(잘 작동할 경우 포인터 역참조를 캐시 라인 친화적인 인덱스 조회로 바꾸는 기법), 그리고 WAL 아카이브와 언두 세그먼트를 객체 스토리지에 두는 실험적 S3 모드도 제공한다. 2026년 기준으로 이 프로젝트는 공개 베타 단계이며 프로덕션 사용은 권장되지 않는다. Supabase는 이를 실험적 옵션으로 제공한다.
이 프로젝트가 성공한다면, 힙을 사소하지 않은 방식으로 선택 사항으로 만들게 된다. 동시에 실제로 구석진 부분까지 건드리기 때문에, 아무도 아직 밟지 않은 TAM API의 엣지 케이스를 가장 먼저 발견할 가능성이 높은 프로젝트이기도 하다. 마케팅 문구보다 버그 트래커를 지켜보는 편이 낫다.
ZHeap는 같은 큰 문제를 겨냥했던 EDB의 더 이른 시도였다. 힙에 죽은 튜플을 쌓는 대신 언두 로그를 사용해 제자리 UPDATE를 구현하려는 접근이었다. 그리고 자금 흐름이 바뀌었을 때 야심찬 스토리지 프로젝트가 어떻게 되는지를 보여주는 전형적인 사례이기도 하다. EnterpriseDB 저장소는 2019년 이후 사실상 정지 상태다. CyberTec이 Heroic Labs의 자금 지원을 받아 이어받았지만, 작업은 간헐적이었다. 좋게 봐도 휴면 상태다. 완전성을 위해 언급할 뿐, 고려 대상은 아니다.
ZHeap이 주는 교훈은 MVCC에 언두 로그 접근을 적용하는 일이 길고 비용이 많이 드는 엔지니어링 프로젝트라는 점이다. “컴파일된다”와 “프로덕션 준비 완료” 사이의 간극은, Postgres 전체 표면과의 통합 작업에 걸리는 수년의 시간으로 측정된다. OrioleDB 역시 정확히 같은 간극을 마주하게 될 것이다.
가장 활동이 밀집된 영역이며, TAM API의 한계가 가장 선명하게 드러나는 곳이기도 하다.
Citus columnar는 살아남은 계보다. 원래의 cstore_fdw는 tableam보다 앞선 시기의 foreign data wrapper였고, 2021년에 Citus 10의 일부가 되면서 TAM API 위로 다시 작성되었다. 이것은 append-only 방식이며, 일반적인 분석 데이터에서 3–10배 수준의 압축을 지원하고, 컬럼 저장소에서 기대하는 스캔 시 장점들(청크 수준 메타데이터 프루닝, 선택적 압축 해제)을 제공한다. UPDATE와 DELETE 비용은 명확하다. Citus columnar 테이블은 이를 전혀 지원하지 않는다. 대량 적재, append, 스캔. 읽기 중심 OLAP 형태에만 맞는다.
이 프로젝트가 살아 있는 이유는 Citus가 살아 있기 때문이다. Microsoft Azure는 Citus를 관리형 제품으로 제공하며, 유지보수 자금도 거기서 나온다. 이미 분산 측면 때문에 Citus를 쓰고 있다면 컬럼형 테이블도 자연스럽게 따라온다. 그렇지 않다면 컬럼형만을 위해 Citus를 선택하는 일은 예전보다 더 어색한 제안이다.
Hydra는 사실상 Citus columnar 포크에 다른 시장 진입 전략을 얹은 것이다. 코드베이스는 같은 계보를 공유하고, 컬럼 형식도 유사하며, 엔지니어링 측 주장에 따르면 Hydra는 상류 Citus보다 벡터화 실행과 컬럼 캐시에 더 많은 투자를 했다. Citus의 분산 확장 요소 없이, 분석을 위한 독립형 컬럼형 Postgres로 포지셔닝된다.
2026년의 Hydra와 Citus columnar가 실제로 의미 있게 다른지는 경험적 질문이다. 포크 시점에 충분히 가까웠기 때문에, 정직한 답을 하려면 실제로 둘을 나란히 돌려봐야 한다. 그것이 바로 다음 글에서 할 일이다. 지금 시점에서 말할 수 있는 것은 이 정도다. Hydra는 존재하고 유지되고 있으며, 이것과 Citus columnar 사이의 선택은 대체로 어느 회사에 베팅하고 싶은지에 달려 있다.
storage_enginestorage_engine 1.0.7 (Saulo Benvenutti, 2026년 4월)은 새로 등장한 주자다. 하나의 확장에 두 개의 TAM을 함께 제공한다. colcompress(컬럼 지향, 벡터화 실행, 청크 수준 min/max 프루닝, MergeTree 스타일 정렬)와 rowcompress(행 지향, 배치 압축, deleted 비트마스크를 통한 DELETE/UPDATE, LRU 압축 해제 캐시)다. 16/17/18 호환성 매트릭스도 적절하다. 작성자의 마이크로벤치마크는 100만 행 워크로드에서 집계 속도 10배 향상과 3–5배 압축을 주장하는데, 범주상 충분히 그럴듯한 수치이며 독립 검증할 가치가 있다.
여기서 아키텍처적으로 흥미로운 선택은 행 지향 압축 TAM이다. 이는 비교적 덜 탐색된 설계 지점이다. 대부분의 프로젝트는 분석을 위해 컬럼 지향을 택하거나, OLTP를 위해 힙에 머문다. 반면 이것은 “랜덤 업데이트가 여전히 있는 워크로드에서 압축을 원한다”에 대한 그럴듯한 답이 된다. 컬럼형 쪽의 MergeTree 형태 정렬은 ClickHouse의 영향이 분명하다. 두 TAM 모두 소규모 팀이 유지하고 있고, 확장 자체도 아직 젊어서 나는 아직 이를 핵심 경로 워크로드에 두지는 않겠지만, 벤치마크 대상으론 충분히 가치가 있다.
pg_cryogenpg_cryogen은 Adjust가 만든 작고 집중된 append-only 압축 TAM이다. 한 번 쓰고 가끔 질의하는 아카이브 형태 워크로드를 위해 명확하게 설계되었다. 잘 압축되고, 스캔도 잘 되며, 그 외의 것을 한다고 주장하지도 않는다. 유지보수는 간헐적이지만, 설계는 좁은 범위를 정직하게 받아들인다. 당신의 문제가 “불변 이벤트 데이터가 수 테라바이트 있고, 전체 힙 저장 비용을 치르지 않으면서 SQL 접근을 위해 이를 Postgres 안에 두고 싶다”라면 pg_cryogen은 살펴볼 가치가 있다.
지난 18개월 동안 가장 선명하게 부상한 범주이며, 설계 혁신의 대부분이 일어나는 곳이기도 하다. 부분적으로는 TAM API가 “Postgres가 자체 컬럼 저장소를 가진다”보다 “외부 컬럼형 엔진 위의 질의 프런트엔드로서의 Postgres”에 훨씬 더 유용하다는 사실이 드러났기 때문이다.
pg_mooncakepg_mooncake는 Postgres 테이블의 columnstore 미러를 Iceberg 또는 Delta Lake 형식으로 만든다. 로컬 디스크나 S3 호환 객체 스토리지에 둘 수 있다. TAM은 Postgres 안에 메타데이터만 저장하고, 실제 데이터는 Parquet와 Iceberg/Delta 매니페스트로 존재한다. pg_mooncake columnstore 테이블에 대한 질의는 내장된 DuckDB에 의해 가속된다. columnstore에 대한 트랜잭션성 insert, update, delete도 지원된다.
이것을 읽는 올바른 방식은 Snowflake의 pg_lake가 답하고 있는 것과 같은 질문에 대한 Postgres 네이티브 답변으로 보는 것이다. 즉, Postgres 사용자가 Postgres를 떠나지 않고도 레이크하우스 스토리지를 쓰게 하려면 어떻게 해야 하는가. pg_mooncake는 TAM API와 인프로세스 DuckDB를 통해 답하고, pg_lake는 별도 pgduck_server 프로세스와 foreign data wrapper를 통해 답한다. 경계는 다르고 절충도 다르지만 목적지는 같다.
pg_mooncake는 Neon에서 베타 확장으로 제공된다. 구현에는 “implement full PG TAM”라는 공개 이슈가 있는데, 이것은 통합의 성숙도에 대해 유용한 사실을 말해 준다. 모든 TAM 콜백이 구현된 것은 아니며, 작성자들도 어느 부분이 날카로운지 정직하게 인정하고 있다.
pg_duckdbpg_duckdb — 공식 DuckDB 팀 확장 — 는 Postgres 백엔드 안에 DuckDB를 내장하고 duckdb 테이블 액세스 메서드(CREATE TABLE foo (...) USING duckdb)를 노출한다. TAM 상주 테이블이 전혀 없어도 원격 Parquet, CSV, JSON, Iceberg, Delta 파일을 직접 질의할 수도 있다.
pg_duckdb의 아키텍처적 질문은 최근 pg_lake 다이제스트 글에서 언급했던 바로 그것이다. DuckDB는 멀티스레드이고 자체 할당기를 가지며, 오류가 무엇인지에 대해서도 자체적인 관점을 갖는다. 이를 Postgres 백엔드와 같은 프로세스에 넣는 것은 결코 가벼운 통합이 아니며, 프로젝트 문서도 그 절충을 명시적으로 밝힌다. “이 데이터에 대해 분석 실행을 원하고 별도 프로세스는 두고 싶지 않다”라면 pg_duckdb가 답이다. “견고한 프로덕션 스토리지 엔진을 원한다”라면, 이것은 주 저장소라기보다 질의 가속 계층에 더 가깝게 포지셔닝된다.
pg_searchParadeDB가 흥미로운 이유는 조금 다르다. 이 조사에서 외부 파일 형식을 Postgres 블록 스토리지 위로 직접 옮겨 심은 유일한 프로젝트이기 때문이다. Tantivy의 전문 검색 형식은 보통 자체 파일에 존재하지만, ParadeDB의 pg_search 확장은 이를 Postgres 페이지 안에 넣는다. 그 결과 WAL, 복제, 버퍼 캐시에 참여하게 된다. 또한 대부분의 사람들이 “컬럼형 스토리지 엔진”이라고 부를 것은 아니지만, 필터링과 정렬을 위한 빠른 필드(fast fields)에 내부적으로 컬럼형 저장을 사용한다.
ParadeDB의 DuckDB-on-Postgres 확장인 pg_analytics는 중단되었고 pg_search에 통합되었다. 이 프로젝트를 추적해 왔다면 알아 둘 만하다. 더 흥미로운 이야기는 블록 스토리지 기법 쪽이다.
경고성 사례다. TimescaleDB 2.18은 투명한 압축 해제를 통해 표준 Postgres 인덱스 메커니즘이 압축된 청크에 대해 동작할 수 있도록 하는 hypercore TAM을 도입했다. 주요 프로젝트가 TAM API를 활용한 사례 중 가장 야심찬 편이었다. 그러나 Timescale 팀은 이를 2.21에서 사용 중단 예정으로 전환했고, 2.22(2025년 9월)에서 종료했다. 실험이 “기대했던 신호를 보여주지 못했다”는 판단 때문이었다. 압축 자체는 여전히 남아 있지만, TAM 없이 동작하는 columnstore 메커니즘으로 돌아갔고, sparse index와 기존 청크 관리 코드를 통해 접근한다.
이 교훈은 곱씹어 볼 가치가 있다. Timescale은 이 목록의 거의 어떤 프로젝트보다도 스토리지 작업에 더 많은 엔지니어와 자금을 투입할 수 있다. 그들은 TAM을 만들었고, 출시했고, 프로덕션에서 돌렸고, 다시 철회했다. 철회 이유는 바로 TAM API가 보기보다 어려운 이유와 겹친다. 컬럼 형태 데이터 위에 튜플 형태 추상화를 올리면, 결국 행 그림자 저장소를 둬야 하거나(그리고 이를 계속 동기화해야 하거나), 특수 사례의 숲을 만들어야 한다(그리고 업그레이드마다 이를 유지해야 한다). Timescale의 사후 분석은 암묵적이지만 변경 로그를 읽으면 충분히 읽힌다.
2026년에 컬럼형 TAM을 평가하고 있다면, “Timescale이 이걸 시도했다가 포기했다”는 사실은 사전 확률에 들어가야 한다. 사형 선고로 받아들이라는 뜻은 아니다. Timescale의 구체적 사용 사례는 범용 컬럼형 TAM보다 제약이 더 많다. 하지만 보정점으로는 분명히 중요하다.
pg_sorted_heappg_sorted_heap 0.13.0 (2026년 5월 5일)은 아주 새롭고 진지하게 볼 가치가 있다. 기본 키 기준으로 물리적으로 정렬된 힙 저장을 유지하면서, 페이지별 zone map으로 범위 조건 프루닝을 수행한다. 여기에 플래너와 통합된 HNSW 인덱스 AM(sorted_hnsw) 및 svec/hsvec 벡터 타입이 짝을 이룬다. 버전 0.13.0은 “fact-shaped” GraphRAG 계약 — (entity_id, relation_id, target_id) 형태로 클러스터링된 fact — 을 안정 표면으로 끌어올렸다.
이 아키텍처 선택은 흥미롭다. 작성자는 범용 TAM을 만들기보다, 특정 형태(PK 기준 정렬, 범위 조건이 많은 질의, 벡터 검색)에 최적화된 TAM을 만들고, 이를 플래너 및 HNSW AM과 pgvector가 하지 못한 방식으로 통합했다. 마이크로벤치마크는 100% Recall@10에서 pgvector halfvec과 동등하거나 더 낫다고 주장하는데, 워크로드 형태를 받아들인다면 충분히 그럴듯한 주장이다. 이것이 TAM API를 올바르게 쓰는 방식이다. 제약 하나를 고르고, 거기에 강하게 최적화하며, 무엇을 잘하는지 사용자에게 정직하게 말하는 것.
cstore_fdw (역사적)cstore_fdw는 Citus columnar의 FDW 기반 조상이다. 아직 존재하긴 하지만, 새로운 작업에 사용해서는 안 된다. 저장소 자체도 대신 Citus columnar를 쓰라고 권한다.
ZedStore는 2019년의 VMware/Pivotal 컬럼형 TAM 프로젝트였지만, 프로덕션 수준 성숙도에 도달하지 못했다. 코드베이스는 고고학적 목적 정도로는 남아 있다. 설계 아이디어(컬럼 데이터의 계층적 조직, 처음부터 HTAP 준수를 시도한 점)는 후속 프로젝트들에 영향을 주었지만, 프로젝트 자체는 막다른 길이다.
**pg_strom**은 GPU 가속을 수행하는 TAM 인접 프로젝트다. 살아 있긴 하지만 목표 사용 사례가 충분히 좁아서, 일반적인 스토리지 엔진 조사에는 들어가지 않는다.
EDB의 Advanced Storage Pack과 여러 상용 벤더의 유사한 엔터프라이즈 전용 모듈도 존재한다. 그러나 소스가 공개되어 있지 않고 설계 선택을 검토할 수 없기 때문에, 이 조사 범위에서는 제외한다.
정직한 답은 2026년의 선택지가 마케팅 자료가 암시하는 것보다 더 제한적이라는 것이다. 몇 가지 패턴은 분명하다.
주요 OLTP 워크로드를 운영하고 있고, 블로트나 쓰기 증폭 문제 때문에 스토리지 엔진을 보고 있다면, 답은 아마 대체 TAM이 아닐 것이다. OrioleDB가 가장 신뢰할 만한 언두 로그 옵션이지만 베타 상태이며, 그대로 취급해야 한다. 다른 힙 대체 후보들은 활발히 개발되고 있지 않다. 실용적인 답은 VACUUM 전략을 고치고, 공격적으로 파티셔닝하고, 기다리는 것이다.
분석 워크로드가 OLTP와 함께 위치한 경우 — 즉 HTAP 형태 — 경계를 어디에 그을지 선택해야 한다. Citus columnar와 Hydra는 업데이트하지 않을 데이터에 대해 읽기 중심 컬럼형 옵션으로 신뢰할 만하다. **pg_mooncake**와 **pg_duckdb**는 DuckDB로 실행을 밀어내고 그에 따르는 운영 복잡성을 받아들일 의향이 있다면 신뢰할 만한 선택지다. **storage_engine**은 벤치마크할 가치가 있는 젊은 도전자지만, 아직 핵심 경로에 둘 단계는 아니다.
워크로드가 시계열이라면, 사용 중단된 Hypercore TAM 없이 TimescaleDB의 네이티브 columnstore를 사용해야 한다. 시계열의 정답은 오랫동안 Timescale이었다.
워크로드가 PK 기준 정렬과 벡터 검색을 결합한다면, **pg_sorted_heap**은 벤치마크를 한 번 돌려볼 가치가 있다. 아직 젊지만, 범위에 대해 정직하고, 덧붙인 opclass가 아니라 플래너 통합형 인덱스 AM을 갖춘 몇 안 되는 프로젝트 중 하나다.
후속 글에서는 동일한 워크로드 — 적재, 점 조회, 범위 스캔, 벡터화 집계, 쓰기 비중이 높은 혼합 형태 — 를 힙, OrioleDB(단서 포함), Citus columnar, Hydra, storage_engine, pg_mooncake, pg_sorted_heap에 대해 실행할 것이다. 이 분류 체계보다 숫자가 더 많은 것을 말해 줄 것이다.