근무하면서 처음 Statsig라는 도구를 접하게 되었습니다. 회의 중 시니어 개발자분들께서 feature flag, 환경별 데이터 서빙, 커뮤니케이션 비용 같은 주제에 대해 이야기하셨는데, 모든 내용을 충분히 이해하지는 못했습니다. 이후 회의가 끝난 뒤 관련 내용을 따로 찾아보며 스스로 정리해보았습니다. 아직 직접 설계하거나 구축해본 경험은 없지만, 공부하면서 이해한 내용을 바탕으로 풀어쓴 글입니다.
목차
- Statsig이란?
- Feature Flag 기본 개념
- 환경별 데이터 서빙 구조
- staging이 이름만 staging인 경우
- 왜 커뮤니케이션 비용이 늘어나는가
1. Statsig이란?
회의에서 Statsig이라는 이름이 처음 등장했을 때는 feature flag 툴 정도로만 이해했습니다. 나중에 찾아보니 feature flag뿐 아니라 A/B 테스트와 제품 분석까지 하나의 플랫폼에서 관리할 수 있는 서비스였습니다. 비슷한 포지션의 서비스로는 LaunchDarkly, Unleash, GrowthBook 등이 있는데, Statsig의 차별점은 실험 설계부터 통계 분석까지 플랫폼 안에서 함께 처리할 수 있다는 점이라고 합니다.
Statsig의 핵심 구성 요소는 세 가지입니다.
Feature Gate는 특정 조건에 따라 기능을 켜거나 끄는 역할을 합니다. 조건은 유저 ID, 이메일 도메인, 국가, 환경 tier, 커스텀 속성 등 다양하게 조합할 수 있습니다. 예를 들어 "내부 직원 이메일을 가진 유저에게만 새 UI를 보여준다"거나 "전체 유저의 10%에게만 새 결제 플로우를 노출한다"는 식의 규칙을 Statsig 콘솔에서 코드 배포 없이 설정할 수 있습니다.
Experiment는 A/B 테스트를 위한 기능입니다. 유저를 여러 그룹으로 나누고 각 그룹에 다른 값을 내려줍니다. Feature Gate가 "켜냐 끄냐"의 이진 판단이라면, Experiment는 "어떤 버전을 보여줄 것인가"의 다변량 판단에 가깝습니다. 실험 결과는 Statsig이 통계적 유의성을 자동으로 계산해 줍니다.
Event 로깅은 실험 결과를 판단하는 데이터 기반입니다. 앱에서 발생하는 사용자 행동(클릭, 구매, 페이지 이탈 등)을 Statsig에 이벤트로 보내면, Statsig은 이를 실험 그룹별로 집계해서 어떤 버전이 더 효과적이었는지 분석합니다. 회의에서 이 이벤트 로깅 부분이 환경 분리 문제와 직결된다는 얘기가 많이 나왔는데, 왜 그런지는 아래에서 다루겠습니다.
SDK는 서버사이드(Node.js, Python, Go 등)와 클라이언트사이드(JavaScript, React Native, iOS, Android 등) 모두 지원합니다. 초기화할 때 SDK Key와 환경 정보를 함께 넘기는데, 이 부분이 환경 분리의 출발점입니다.
await Statsig.initialize(
process.env.STATSIG_SDK_KEY, // 환경별로 다른 Key
{ environment: { tier: process.env.ENV_TIER } } // 'development' | 'staging' | 'production'
);
2. Feature Flag 기본 개념
Feature Flag(또는 Feature Toggle)는 코드를 새로 배포하지 않고도 특정 기능의 노출 여부를 런타임에 제어하는 패턴입니다. 이름만 들으면 if문처럼 보이지만, 실제로 팀에서 운용할 때는 꽤 다양한 목적으로 활용됩니다.
Feature Flag를 쓰는 이유
가장 흔한 사용 사례는 점진적 롤아웃입니다. 새 기능을 전체 유저에게 한꺼번에 배포하는 대신, 처음에는 내부 직원에게만, 그다음에는 베타 유저 5%에게, 그다음에는 50%로 단계적으로 늘려가는 방식입니다. 문제가 생기면 배포를 롤백하는 대신 플래그만 꺼버리면 되기 때문에 리스크가 크게 줄어듭니다. 배포 자체는 이미 되어 있고, 기능의 노출 여부만 조정하면 되기 때문에 복구 속도도 훨씬 빠릅니다.
두 번째 사용 사례는 트렁크 기반 개발(Trunk-Based Development) 지원입니다. 아직 완성되지 않은 기능의 코드가 main 브랜치에 이미 머지되어 있더라도, 플래그로 꺼둠으로써 실제 유저에게는 노출되지 않도록 할 수 있습니다. 오래 살아있는 피처 브랜치로 인한 머지 충돌을 줄이고, 팀 전체가 하나의 브랜치 위에서 작업하면서도 기능 단위로 독립적인 릴리즈 사이클을 가져갈 수 있습니다.
세 번째는 킬 스위치입니다. 특정 기능이 예상치 못한 부하를 유발하거나 장애와 연관됐을 때, 코드 수정이나 배포 없이 즉각적으로 비활성화할 수 있는 비상구 역할을 합니다.
네 번째는 유저 세그먼트별 기능 분기입니다. 프리미엄 유저에게만 고급 기능을 보여주거나, 특정 국가 유저에게만 현지화된 기능을 노출하는 식으로, 단순한 켜짐/꺼짐을 넘어서 유저 특성에 따른 경험 분기를 런타임에 만들 수 있습니다.
Statsig에서의 기본 사용 흐름
코드 레벨에서는 아래처럼 단순합니다. 플래그를 평가하고, 그 결과에 따라 분기하면서 이벤트를 로깅하는 패턴입니다. 이 이벤트 로그가 나중에 실험 결과 분석의 기반이 됩니다.
const user = { userID: 'user_123', email: 'user@example.com' };
const showNewUI = Statsig.checkGate(user, 'new_checkout_ui');
if (showNewUI) {
renderNewCheckout();
Statsig.logEvent(user, 'checkout_viewed', 'new_ui');
} else {
renderLegacyCheckout();
Statsig.logEvent(user, 'checkout_viewed', 'legacy_ui');
}
주목할 점은 checkGate의 결과가 코드가 아니라 Statsig 콘솔 설정에 의해 결정된다는 것입니다. 재배포 없이 콘솔에서 규칙을 바꾸는 것만으로 동작이 달라집니다. 이것이 Feature Flag의 핵심 가치입니다.
3. 환경별 데이터 서빙 구조
회의에서 가장 많이 나온 주제 중 하나가 dev 데이터, staging 데이터, production 데이터를 어떻게 분리해서 서빙할 것인가였습니다. 처음에는 왜 이게 복잡한 문제인지 잘 몰랐는데, 들을수록 환경 변수 하나 바꾸는 문제가 아니라는 걸 알게 됐습니다.
Statsig은 development, staging, production 세 가지 환경 tier를 지원합니다.
환경 tier 주요 용도 권장 데이터 전략
| development | 로컬 개발, 기능 구현 중 빠른 반복 | mock 데이터 또는 dev 전용 데이터셋 |
| staging | QA, 통합 테스트, 릴리즈 전 검증 | stg 전용 데이터셋, prd와 완전 분리 |
| production | 실 서비스 트래픽 | 실 데이터 축적, 실험 분석의 기준 |
환경별로 다를 수 있는 것들
환경 tier가 달라지면 세 가지가 달라집니다.
첫째, 플래그 켜짐/꺼짐 여부가 환경마다 다를 수 있습니다. 개발 중인 기능을 dev에서는 켜두고, staging에서는 QA 팀에게만 켜두고, production에서는 아직 비활성화해두는 식으로, 코드 배포 없이 노출 범위를 조율할 수 있습니다.
둘째, 이벤트 데이터가 쌓이는 데이터셋이 다릅니다. dev나 staging에서 발생한 이벤트가 production 데이터셋에 섞이면 A/B 테스트 결과가 오염됩니다. QA 팀이 staging에서 특정 버튼을 수백 번 클릭한 이벤트가 production 전환율 집계에 포함된다면, 실험 결과를 신뢰할 수 없게 됩니다.
셋째, SDK Key 자체가 다릅니다. Statsig 콘솔에서 환경별로 별도의 SDK Key를 발급할 수 있고, Key가 다르면 이벤트 데이터가 물리적으로 분리됩니다. 이것이 환경 분리에서 가장 단순하고 확실한 방어선입니다.
SDK Key가 단순한 인증 토큰이 아닌 이유
회의를 듣다가 "SDK Key를 환경별로 분리해야 한다"는 말이 나왔는데, 처음엔 보안 때문인 줄 알았습니다. 사실은 그게 아니라, Statsig 입장에서 SDK Key는 "이 이벤트가 어느 환경 데이터셋에 속하는가"를 결정하는 라우팅 키이기 때문이었습니다. staging 서버에 실수로 production SDK Key가 주입되면, staging 트래픽이 그대로 production 데이터셋에 쌓히게 됩니다.
4. staging이 이름만 staging인 경우
회의에서 가장 흥미로웠던 부분이 이 주제였습니다. 누군가 "stg에서 k8s 인프라가 따로 있는 거 맞냐?"고 물었고, "이름만 stg이고 네임스페이스만 분리한 거다"라는 대답이 나왔습니다. 그때는 그게 왜 문제인지 바로 이해가 안 됐는데, 찾아보면서 이해하게 됐습니다.
인프라 분리와 네임스페이스 분리의 차이
이상적인 환경 분리는 클러스터 자체가 다른 경우입니다. production 클러스터와 staging 클러스터가 각각 독립된 노드, 네트워크, 데이터베이스를 가지고 있으면, 한 환경의 트래픽이 다른 환경에 영향을 줄 가능성이 구조적으로 차단됩니다.
반면 많은 팀에서 실제로 운영하는 방식은 같은 클러스터 안에서 네임스페이스(namespace)만 분리하는 구조입니다.
# 이상적인 분리
cluster-production → prd 전용 노드, 네트워크, DB
cluster-staging → stg 전용 노드, 네트워크, DB
# 현실에서 자주 보이는 구조
cluster-shared
├── namespace: production
└── namespace: staging ← 같은 클러스터 안에 존재
네임스페이스 분리 자체가 나쁜 것은 아닙니다. 논리적 격리, 리소스 쿼터, RBAC을 네임스페이스 단위로 적용할 수 있고, 별도 클러스터보다 비용도 훨씬 효율적입니다. 소규모 팀이나 초기 단계에서는 충분히 합리적인 선택입니다.
문제는 회의에서 나온 말처럼 "명확하게 인프라가 나뉘어져 있으면 괜찮은데, 나뉘어진 게 아니어서 어려운 것" 입니다. 클러스터가 분리됐다고 착각하거나, staging이 production과 완전히 독립적이라고 가정하고 설정을 관리하면 문제가 생깁니다.
어떤 문제가 생기나
데이터 오염이 가장 직접적인 문제입니다. staging 파드에 주입되는 환경 변수 중 Statsig SDK Key가 실수로 production Key로 설정되면, staging에서 발생한 모든 이벤트가 production 데이터셋에 쌓힙니다. QA 엔지니어가 새 기능을 테스트하면서 발생시킨 이벤트들 자동화 테스트가 만들어내는 이벤트들이 production A/B 실험 결과에 포함됩니다.
지표 왜곡도 뒤따릅니다. DAU, 전환율, 이탈률 같은 핵심 지표들이 테스트 트래픽으로 인해 왜곡됩니다. 특히 자동화 테스트가 밤새 돌아가는 경우, 다음 날 아침 대시보드를 열면 아무도 모르는 사이에 지표가 이상해져 있을 수 있습니다.
디버깅 비용 증가도 큰 문제입니다. 데이터가 섞였다는 사실 자체를 발견하기가 어렵습니다. 실험 결과가 왜 이렇게 나왔지?라는 의문에서 시작해 이벤트 로그를 뒤지고, staging 설정을 확인하고, SDK Key를 추적하는 과정은 상당한 시간이 걸립니다. 문제가 며칠 전부터 시작됐다면 이미 많은 데이터가 오염된 상태라 해당 기간의 실험 결과 자체를 폐기해야 할 수도 있습니다.
stg에서 prd 데이터를 못 쌓게 할 수 있을까?
stg에서 prd 데이터를 못 쌓게 할 수도 있지 않나라는 말도 가능하긴 합니다. 다만 완벽한 방어를 위해서는 여러 레이어에서 동시에 접근해야 합니다. 설정 레이어에서는 SDK Key를 환경별로 철저히 분리하는 것이 가장 먼저입니다. Kubernetes에서는 네임스페이스별로 다른 Secret 오브젝트를 만들고, 각 파드가 자신의 네임스페이스 Secret만 참조하도록 RBAC을 설정합니다.
# staging 네임스페이스 전용 Secret
apiVersion: v1
kind: Secret
metadata:
name: statsig-secret
namespace: staging # production 네임스페이스에는 별도 Secret 존재
stringData:
STATSIG_SDK_KEY: "secret-stg-xxxxxxxx" # staging 전용 Key
ENV_TIER: "staging"
네트워크 레이어에서는 staging 네임스페이스에 NetworkPolicy를 적용해서 production 내부 서비스에 접근하지 못하도록 막을 수 있습니다. 단, Statsig은 외부 SaaS이기 때문에 NetworkPolicy만으로는 분리가 안 됩니다. production과 staging 모두 같은 api.statsig.com 도메인을 사용하기 때문에, 결국 SDK Key 분리가 방어선이 됩니다.
핵심은 회의에서 나온 말 그대로입니다. 인프라가 진짜로 분리되지 않으면 설정만으로는 완벽히 막을 수 없습니다. 설정은 사람이 관리하고, 사람은 실수를 합니다. 인프라 수준의 격리가 있어야 그 위에 설정 방어가 의미 있게 작동합니다.
5. 왜 커뮤니케이션 비용이 늘어나는가
환경 분리 얘기를 하면서 커뮤니케이션 비용 문제도 함께 나왔습니다. 처음에는 인프라 얘기를 하다가 왜 갑자기 커뮤니케이션 얘기가 나오는지 맥락을 잘 못 잡았는데, 결국 연결된 문제였습니다.
모호한 환경 = 모호한 소통
인프라나 설정이 명확하지 않으면 기술적인 문제가 생기기 전에 먼저 사람들 사이에 혼선이 생깁니다.
예를 들어 QA 엔지니어가 "이 플래그 staging에서도 켜줘"라고 요청하면, 이 한 마디에 여러 해석이 가능합니다. staging 네임스페이스 기준인지, Statsig 콘솔의 staging 환경 tier 기준인지, staging SDK Key 기준인지가 명확하지 않습니다. 환경이 명확히 분리되어 있지 않으면 요청을 받은 사람은 반드시 되물어봐야 합니다. 이 확인 과정이 매번 반복됩니다.
데이터를 볼 때도 마찬가지입니다. PM이 "이번 실험 결과 어때?"라고 물었을 때, 데이터 분석가가 보는 대시보드에 staging 이벤트가 섞여 있다면 결과 해석 자체가 어긋납니다. 발견하려면 이벤트 로그를 상세히 들여다봐야 하고, 발견한 뒤에는 "얼마나 섞였는지"를 역추적해야 합니다. 여기에 관련된 엔지니어, 데이터 분석가, PM이 모두 시간을 쓰게 됩니다.
온보딩에서도 드러납니다. 새로 합류한 팀원에게 "staging이 있긴 한데 사실 네임스페이스만 분리된 거고, SDK Key는 여기 있는 게 맞는 건데 실수로 저걸 쓰면 prd에 데이터가 쌓이니까 조심해야 해"라고 설명해야 한다면, 그 자체가 구조가 명확하지 않다는 신호입니다. 설명하기 복잡한 구조는 실수하기 쉬운 구조입니다.
쌓이면 어떻게 되나
단기적으로는 슬랙에서 확인 메시지가 오가고, 회의에서 그게 어느 환경 기준이야?라는 질문이 반복되는 불편함입니다.
중기적으로는 신뢰도 문제가 생깁니다. 이 숫자 믿을 수 있어?라는 의문이 생기기 시작하면, 데이터 기반 의사결정의 근거 자체가 흔들립니다. 어느 정도 오염됐는지 파악이 안 되는 상태에서는 어떤 숫자도 온전히 신뢰하기 어렵습니다.
장기적으로는 변화에 대한 저항이 생깁니다. 플래그를 잘못 건드렸다가 prd 데이터를 오염시킬 수 있다는 불안감이 퍼지면, 사람들은 플래그를 적극적으로 활용하기보다 조심스럽게 피하게 됩니다. 좋은 도구를 도입해 놓고 두려워서 제대로 쓰지 못하는 상황이 됩니다.
글을 마치며
회의에서 들은 내용을 정리하면서, 처음에는 단순한 툴 사용법 문제인 줄 알았던 것이 사실은 인프라 구조, 데이터 신뢰성, 팀 소통 방식까지 연결된 문제라는 걸 알게 됐습니다. Statsig 자체의 기능보다, 그 툴이 우리 인프라 환경 위에서 어떻게 동작하는지를 이해하는 게 먼저라는 것도 느꼈습니다. 아직 직접 설계하거나 구축해본 경험은 없지만, 이번에 정리하면서 왜 그런 논의가 오갔는지는 이해할 수 있게 됐습니다.
