Supabase Realtime과 ETL을 헷갈리면, 실시간 기능이 데이터 파이프라인이 된다
사용자 화면을 즉시 바꾸는 이벤트와 나중에 반드시 분석되어야 하는 데이터를 같은 WebSocket 구독으로 처리하고 있지 않은가?
Supabase Realtime과 ETL을 헷갈리면, 실시간 기능이 데이터 파이프라인이 된다
- 카테고리: web_app_dev
- 예상 읽기 시간: 10분
- 오늘의 질문: “사용자 화면을 즉시 바꾸는 이벤트”와 “나중에 반드시 분석되어야 하는 데이터”를 같은 WebSocket 구독으로 처리하고 있지 않은가?
- 핵심 출처:
- Realtime vs ETL: Choosing the Right Supabase Tool - 게시일: 페이지 확인 결과 미표기, 확인일: 2026-06-13
- Introducing Supabase ETL - 게시일: 2025-12-02, 확인일: 2026-06-13
- Postgres Changes | Supabase Docs - 게시일: 문서 페이지 미표기, 확인일: 2026-06-13
- Realtime Authorization | Supabase Docs - 게시일: 문서 페이지 미표기, 확인일: 2026-06-13
- Broadcast | Supabase Docs - 게시일: 문서 페이지 미표기, 확인일: 2026-06-13
1. 왜 지금 봐야 하나
Supabase가 “Realtime이냐 ETL이냐”를 별도 글로 설명한 이유는 단순 기능 비교가 아니다. 많은 웹앱 팀이 postgres_changes를 붙이고 나서 “DB 변경을 어디든 흘려보낼 수 있겠네”라고 생각한다. 처음에는 관리자 대시보드, 알림 배지, 채팅 목록 갱신까지 잘 된다. 문제는 그 다음이다. 같은 흐름을 분석 적재, 감사 로그, 외부 시스템 동기화에도 쓰기 시작하면 실시간 기능이 데이터 파이프라인처럼 행동하기를 기대하게 된다.
하지만 Realtime의 핵심 약속은 “접속 중인 사용자에게 지금 보이는 화면을 빠르게 갱신한다”에 가깝다. ETL의 약속은 “모든 변경을 목적지에 빠짐없이 옮긴다”에 가깝다. 둘 다 Postgres의 logical replication, WAL, publication 같은 단어를 공유하지만 제품 계약은 다르다.
2. 핵심 개념
오늘의 핵심 개념은 **전달 계약(delivery contract)**이다.
- Realtime: 낮은 지연 시간, WebSocket, 사용자 경험, best-effort 성격
- ETL: 변경 데이터 캡처(CDC), 영구적인 적재 흐름, 분석 목적지, 누락 방지
Supabase 문서에 따르면 Postgres Changes는 테이블을 supabase_realtime publication에 추가하고, 클라이언트가 INSERT, UPDATE, DELETE 같은 이벤트를 구독하는 방식으로 동작한다. 이때 RLS가 켜진 테이블에서는 각 사용자가 해당 변경을 읽을 수 있는지 확인된다. 예를 들어 한 row 변경에 100명이 구독 중이면, 각 구독자 관점의 권한 확인 비용이 생긴다.
반대로 Supabase ETL은 Postgres 변경을 BigQuery나 Analytics Buckets 같은 분석 목적지로 복제하는 CDC 파이프라인이다. 초기 복사 후 스트리밍 모드로 전환하고, INSERT, UPDATE, DELETE, TRUNCATE를 목적지에 반영하는 쪽에 초점이 있다.
3. 최신 이슈와 연결
Supabase의 최근 문서와 블로그를 함께 보면 Realtime 내부에도 선택지가 늘었다.
첫째, Postgres Changes는 DB row 변경을 클라이언트에 직접 흘려보낸다. 구현은 편하지만 구독자 수와 RLS 정책 복잡도에 따라 DB 권한 확인 비용이 커질 수 있다.
둘째, Broadcast와 Presence는 “DB row 변경”보다 “채널 메시지”에 가깝다. Broadcast from Database는 트리거나 함수로 realtime.messages에 메시지를 넣고, Realtime이 이를 WebSocket으로 전달한다. 문서에 따르면 private/public 플래그와 클라이언트 채널 설정이 맞아야 하고, Realtime Authorization은 realtime.messages에 대한 RLS 정책으로 채널 접근을 판단한다.
셋째, ETL은 화면 갱신이 아니라 분석 저장소로의 복제다. Supabase ETL 소개 글은 BigQuery를 공식 목적지로 설명하고, 분석 쿼리를 운영 Postgres에서 분리하는 이유를 강조한다.
4. 개발자 관점 해석
실무 판단은 “이 이벤트가 놓쳐져도 되는가?”로 시작하면 된다.
채팅방 상단의 “누가 입력 중” 표시는 놓쳐져도 괜찮다. 잠깐 끊기면 다음 이벤트에서 회복된다. 이건 Presence나 Broadcast에 어울린다.
새 주문이 관리자 화면에 즉시 나타나는 것은 Realtime에 어울린다. 다만 사용자가 30초간 오프라인이었다가 돌아왔을 때 누락분을 반드시 복구해야 한다면, 재접속 시 REST/RPC로 현재 상태를 다시 읽는 보정 루프가 필요하다. Realtime은 화면을 빠르게 흔들어 깨우는 신호이고, 최종 진실은 DB 조회다.
반면 결제 이벤트, 감사 로그, 실험 분석 이벤트, CRM 동기화처럼 “하나라도 빠지면 안 되는” 흐름은 Realtime 구독으로 처리하면 위험하다. 여기서는 ETL, job queue, outbox table, 재시도 가능한 worker처럼 읽은 위치와 실패 복구를 관리하는 구조가 필요하다.
5. 내 프로젝트에 적용할 체크포인트
- 지금
postgres_changes를 쓰는 곳이 UI 갱신인지, 데이터 복제인지 이름으로 표시했는가? - 재접속 후 놓친 이벤트를 다시 가져오는
refetch경로가 있는가? - RLS 정책이 복잡한 테이블을 많은 사용자가 동시에 구독하고 있지 않은가?
- “분석용 이벤트”를 클라이언트 WebSocket 수신에 의존하고 있지 않은가?
- Broadcast private/public 설정과 클라이언트
config: { private: true }가 일치하는가? service_role또는 secret key를 클라이언트에 노출하지 않는가?- 운영 대시보드에서 필요한 것은 “모든 변경 이력”인지 “현재 상태의 빠른 반영”인지 구분했는가?
6. 오늘 10분 액션
10분만 써서 프로젝트의 실시간 기능을 표로 나눠보자.
이벤트 이름 | 소비자 | 놓쳐도 되는가 | 복구 방법 | 권장 도구
message_inserted | 채팅 화면 | 대부분 안 됨 | 재접속 시 최근 메시지 조회 | Realtime + refetch
user_typing | 같은 방 사용자 | 됨 | 다음 typing 이벤트 | Presence/Broadcast
payment_succeeded | 분석/정산 | 안 됨 | 재시도/적재 상태 추적 | ETL 또는 worker/outbox
admin_order_badge | 관리자 UI | 잠깐은 됨 | 현재 주문 목록 재조회 | Realtime + refetch
표에서 “놓치면 안 됨”인데 권장 도구가 Realtime으로만 끝나는 항목이 있으면 빨간불이다. 오늘은 코드를 고치지 않아도 된다. 먼저 전달 계약을 적는 것이 핵심이다.
7. 더 볼 자료
- Supabase Realtime Postgres Changes 문서: publication 설정, RLS, DELETE old record 제약, private schema 권한을 확인한다.
- Supabase Realtime Authorization 문서:
realtime.messages,realtime.topic(), JWT claim 기반 정책을 확인한다. - Supabase Broadcast 문서: database-sourced broadcast, private/public 매칭, replay 제약을 확인한다.
- Supabase ETL 소개 글: 운영 Postgres와 분석 워크로드를 분리해야 하는 이유를 확인한다.
중복 회피 메모
최근 웹앱 글은 Supabase Auth 이메일, RLS Tester, Hono 보안 릴리스, Node TypeScript 실행 계약, Next.js AI 디버깅을 다뤘다. 이번 글은 Supabase를 다시 다루지만 인증 이메일이나 RLS 정책 테스트가 아니라, Realtime/Postgres Changes/Broadcast/ETL의 전달 계약과 누락 허용 여부를 기준으로 실시간 UX와 데이터 파이프라인을 분리하는 설계 판단에 집중했다.
핵심 출처
로그인하면 이 글을 북마크하고, 나만 보는 한 줄 메모를 남길 수 있어요.
댓글 0
최신순 ▾혹시 이 글을 읽는 동료 개발자가 있다면, GitHub으로 로그인하고 한 줄 흔적을 남겨줘요. (스팸 방지용 로그인이에요)