Rapidly scaling online storage to serve over 1 billion ChatGPT users
🖼️ 인포그래픽

🖼️ 4컷 인포그래픽

💡 한 줄 요약
OpenAI는 매주 10억 명 이상이 사용하는 제품을 지원하기 위해 Habitat을 Python 라이브러리에서 독립 서비스로 전환하고, 배포 통제와 보안을 중앙화하면서 asyncio 지연과 부하 편중을 줄여 온라인 저장소를 확장했다.
📌 핵심 요약
- Habitat은 거의 40개 지리적 리전에서 초당 7,000만 건 이상의 요청과 500페타바이트 이상의 데이터를 처리하며, 매주 10억 명 이상이 사용하는 OpenAI 제품을 지원한다. 원문은 지난 3년 동안 매년 10배 이상 성장했다고 설명한다.
- 2024년 중반 Azure Cosmos DB 접근을 단순화하는 Python 라이브러리로 시작했지만, 2025년 중반에는 수십 개 서비스의 배포 조율과 구버전 클라이언트 복귀에 따른 장애가 한계로 드러났다. 독립 서비스 전환으로 배포·관측·접근 통제·감사 로깅을 중앙화했다.
- Python 서비스는 네트워크 지연과 CPU·메모리 비용을 늘렸지만, 당시에는 제품 개발과 플랫폼 안정성을 우선했다. 100배 규모에서는 재작성이 거의 확실하다고 보았으며, Codex와 GPT가 향후 이전을 가능하게 할 것이라는 기대가 맞았다고 서술한다.
- asyncio는 I/O 동시성을 제공하지만 GIL을 우회하는 CPU 병렬성을 제공하지 않는다. CPU 작업으로 발생하는 이벤트 루프 스케줄링 지연이 p99 이상 요청 지연을 지배할 수 있어, 지연을 직접 측정하고 프로세스별 동시 요청을 줄이는 대신 Python 워커 프로세스를 대규모로 늘렸다.
- Statsig 설정을 매분 동시에 파싱하면서 발생한 지연은 설정 축소, 갱신 주기 연장, 실행 시점 분산으로 완화했다. 클라이언트 연결 풀은 일부 프로세스에 평균의 5~10배 동시 요청을 집중시키기도 했으며, 제공된 본문은 관련 사례 설명 도중 끊겨 후속 해결 방식은 확인할 수 없다.
🧩 주요 포인트
- 수십 개 서비스에 분산된 클라이언트 갱신이 장애로 연결됨 → 저장소 제어를 독립 서비스에 모아 변경 조율 부담과 보안 정책의 분산을 줄임.
- 급성장 속에서 Python의 성능 비용을 한시적으로 수용함 → 제품 개발과 안정성을 먼저 확보하고, 장기적인 언어 이전은 후속 과제로 배치함.
- 이벤트 루프 대기와 연결 풀의 부하 편중이 긴 지연을 유발함 → 자원 사용률뿐 아니라 스케줄링 지연과 프로세스별 동시 요청 분포까지 관리할 필요가 있음.
🧠 상세 정리
1. 급성장하는 제품을 지탱하는 온라인 저장소
OpenAI 제품에서 로그인하거나 Codex 설정을 확인하고 ChatGPT 대화를 시작할 때는 응답 전에 여러 차례 데이터를 조회할 수 있으며, 조회가 느리거나 실패하면 제품의 속도와 가용성에 직접 영향을 준다. 이를 지원하는 Habitat은 현재 거의 40개 지리적 리전에서 초당 7,000만 건 이상의 요청을 처리하며, 매주 10억 명 이상이 사용하는 제품을 뒷받침한다. 원문은 Habitat이 2년 전 단일 데이터베이스에 연결된 작은 Python 라이브러리에서 출발해 500페타바이트 이상의 데이터를 제공하는 분산 시스템으로 발전했다고 설명한다. 특별히 어려웠던 점은 규모 자체보다 지난 3년 동안 매년 10배 이상 성장하는 수요를 감당하면서 플랫폼의 성숙도도 높여야 했다는 것이다. 따라서 기존 구성 요소의 성능을 최대한 끌어내고 저장소·컴퓨팅 용량 부족을 막아 근본적인 투자를 위한 시간을 확보하는 순서가 중요했다.
2. 데이터베이스 관리를 추상화한 Python 라이브러리
Habitat은 제품 엔지니어가 데이터베이스 관리를 직접 고민하지 않아도 된다는 목표로 2024년 중반 시작됐으며, 초기에는 ChatGPT의 주 서버와 연동하는 작은 Python 라이브러리였다. 제한된 작업 인터페이스를 제공하고 내부적으로 이를 Azure Cosmos DB 작업에 연결해 제품 팀의 데이터 저장과 조회를 단순화했다. 데이터의 종류와 위치, 요청 허용 여부를 판단하는 것뿐 아니라 스키마 조회, 라우팅, 암호화, 직렬화, 요청 형태 조정, 연결 풀 관리까지 맡았다. 제품 엔지니어는 데이터가 Azure Cosmos DB에서 오는지, 캐시나 다른 저장소에서 오는지도 고려할 필요가 없었다. 셀프서비스 Postgres와 Azure Cosmos DB 사용을 줄이려는 중앙 차원의 적극적인 추진이 없었는데도 빠르게 채택됐으며, 개발자들은 공유 라이브러리에 클라이언트 캐싱·압축·암호화 같은 기능을 쉽게 추가할 수 있었다.
3. 분산된 클라이언트 배포가 드러낸 운영 한계
2025년 중반에는 Habitat 계층이 복잡해지고 OpenAI의 서비스 수가 늘어나면서, 클라이언트 구현에 의존한 하위 호환 프로토콜 변경이 사실상 감당하기 어려워졌다. 대표 사례는 단일 리전 장애의 영향 범위를 줄이기 위해 핵심 데이터를 지역별 Azure Cosmos DB 계정으로 옮기는 작업이었다. 추가 라우팅 로직을 기능 플래그 뒤에 배포하고 모든 클라이언트에 반영하는 데 며칠이 걸렸으며, 샤딩 검증용 섀도잉과 버그 수정도 각각 추가 배포 시간을 요구했다. 마침내 기능을 켤 준비가 됐을 때 한 팀이 무관한 이유로 서비스를 롤백하면서 결함이 있던 이전 클라이언트로 돌아갔고, 그 결과 피하려던 장애가 발생했다. 이 경험은 수십 개 서비스와 팀에 걸친 갱신 조율이 취약하고 비효율적이며 운영 실패로 이어질 수 있음을 보여줬고, Habitat을 별도 서비스로 분리하는 계기가 됐다.
4. 독립 서비스로 배포와 보안 통제 중앙화
저장소 로직을 독립 서비스로 분리하면서 Habitat은 배포, 관측, 플랫폼 개선을 한곳에서 통제할 수 있게 됐다. 제품별로 흩어진 라이브러리 갱신을 조율하는 대신 중앙에서 개선을 적용해 모든 OpenAI 제품이 즉시 혜택을 받도록 하는 것이 전환의 핵심이었다. 중앙 서비스는 데이터 보안과 개인정보 보호 기능을 일관되게 적용하는 단일 통제 지점도 제공한다. Habitat은 이 지점에서 접근 통제 정책과 감사 로깅을 적용하고 Azure Cosmos DB 같은 하부 저장소 자원에 대한 접근을 제한한다. 원문은 이러한 역할이 외부 주체뿐 아니라 내부 주체와 에이전트의 무단 접근으로부터 사용자 데이터를 보호하는 데 중요하다고 설명하며, 서비스 전환을 운영 편의와 데이터 보호를 함께 강화한 변화로 제시한다.
5. Python 유지라는 의도적인 기술 부채
독립 서비스가 필요해졌을 때 OpenAI는 Python을 즉시 다른 언어로 바꾸지는 않았으며, 로컬 라이브러리 실행보다 네트워크 지연과 CPU·메모리 비용이 늘어난다는 점을 인식하고 있었다. 또한 100배 규모에서는 Python의 비효율성을 받아들이기 어려워 결국 재작성이 거의 확실하다고 판단했다. 그럼에도 당시 우선순위는 비용 최적화보다 제품 개발의 제약 해소와 플랫폼 안정성 확보였으므로, 단기적인 성능 손해를 의도적인 기술 부채로 수용했다. 이를 통해 핵심 API와 견고한 인프라를 먼저 구축하고, 향후에는 발전한 Codex와 GPT가 언어 이전을 가능하게 할 것이라고 기대했으며 원문은 그 기대가 맞았다고 서술한다. 다만 평균적인 사용자 요청 하나가 수백 번의 데이터베이스 호출을 일으키므로 가장 느린 호출이 체감 속도를 좌우했고, Python을 유지하더라도 지연 분포의 긴 꼬리를 관리하는 일은 미룰 수 없었다.
6. asyncio 스케줄링 지연을 직접 측정
asyncio는 I/O 중심 작업을 동시에 진행하도록 돕지만 Python GIL을 우회해 CPU 병렬성을 제공하지는 않으며, Habitat은 요청 중계 외에도 라우팅·압축·암호화·체크섬과 여러 백그라운드 작업을 수행한다. 초기 서비스 출시 전 p99 이상 지연 요청의 추적에서는 하부 저장소가 빠르게 응답했는데도 코루틴이 다시 실행돼 응답을 해석할 차례를 기다리느라 요청이 멈추는 현상이 자주 나타났다. 따라서 메모리·CPU·네트워크·디스크의 사용률과 포화도에 더해 이벤트 루프가 얼마나 바쁜지 측정하는 것이 중요했다. 주기적으로 예약한 백그라운드 작업의 예정 실행 시각과 실제 실행 시각 차이를 기록하자, 높은 부하와 비싼 작업이 겹칠 때 비교적 적은 동시 요청만으로도 수백 밀리초에서 일부 극단적인 경우 수초의 지연이 발생할 수 있었다. 이에 각 프로세스의 동시 요청 수를 작게 유지하고 Python 워커 프로세스 수를 대규모로 늘리는 방식을 택했다.
7. Statsig 설정 갱신이 만든 동시 정체
초기 서비스 운영 중 실시간 CPU 프로파일링으로 확인한 높은 asyncio 지연의 한 원인은 Statsig 기능 플래그 설정을 주기적으로 JSON 파싱하는 작업이었다. 기본 설정은 모든 서비스의 운영 규칙을 포함한 구성을 매분 갱신하되 실행 시점을 분산하지 않았고, 다른 아키텍처 결정에 따라 파드 하나에는 최대 8개의 Python 프로세스가 실행됐다. 이 두 조건이 겹치면서 매분 파드의 모든 워커가 진행 중인 요청 처리를 멈추고 거대한 설정 파일을 파싱하는 순간이 생겼다. 원인을 파악한 뒤에는 해당 용도에 맞게 설정 크기를 줄이고 갱신 간격을 늘리며 이러한 백그라운드 작업의 실행 시점에 변동을 추가했다. 이 사례는 요청 처리 외부의 주기적 CPU 작업도 워커 전체를 동시에 정체시켜 긴 요청 지연을 만들 수 있고, 실제 서비스 프로파일링이 그 원인을 찾는 데 유효했음을 보여준다.
8. 연결 풀과 프로세스 간 부하 편중
낮은 asyncio 지연을 유지하려면 서버 프로세스 사이에 요청을 고르게 분산해야 하지만, 원문은 조정되지 않은 클라이언트 연결 풀이 이 목표와 충돌할 수 있다고 설명한다. 동시 요청이 많은 클라이언트 프로세스라도 서버 연결을 소수만 만들면 전체 부하가 소수의 서버 프로세스에 집중될 수 있기 때문이다. 부하 분산 방식을 조정하기 전에는 프로세스별 사용률 차이가 컸으며, 일부 프로세스가 평균의 5~10배에 달하는 동시 요청을 처리했다. 이는 전체 자원 사용률만으로는 개별 프로세스의 과부하와 그에 따른 스케줄링 지연을 충분히 설명하기 어렵다는 앞선 논점과 이어진다. 다만 제공된 본문은 이 문제를 발견한 우발적 사건을 소개하는 문장 중간에서 끝나므로, 해당 사건의 전체 경위와 이후 연결 풀·부하 분산 구현의 구체적인 해결 방식은 확인할 수 없다.
🧾 핵심 주장 / 시사점
- Habitat의 전환은 공유 라이브러리가 개발 편의를 제공하더라도, 서비스 수와 변경 복잡성이 커지면 배포 조율 자체가 신뢰성의 제약이 될 수 있음을 보여준다.
- Python 유지 결정은 장기적인 효율성 문제를 인식하면서도 제품 개발과 플랫폼 안정성을 먼저 확보한 우선순위 선택이며, 원문은 이를 의도적인 기술 부채로 설명한다.
- 긴 요청 지연은 하부 저장소의 응답 속도뿐 아니라 응답 이후의 실행 대기, 주기적 설정 파싱, 프로세스별 부하 편중에서도 발생하므로 병목을 구분해 관측해야 한다.
✅ 액션 아이템
- Habitat의 독립 서비스 전환을 기준으로 배포 조율 부담과 접근 통제 중앙화의 효과를 검토한다.
- Python 서비스의 p99 이상 요청 지연을 평가할 때 이벤트 루프 스케줄링 지연과 프로세스별 동시 요청 분포를 함께 확인한다.
- Statsig 설정 축소·갱신 주기 연장·실행 시점 분산의 적용 여부와 연결 풀의 평균 대비 5~10배 부하 편중을 점검한다.
❓ 열린 질문
- Habitat의 독립 서비스 전환 이후 수십 개 서비스의 배포 조율 부담과 구버전 클라이언트 관련 장애는 얼마나 줄었는가?
- Python 워커 프로세스를 늘리고 프로세스별 동시 요청을 줄인 뒤 p99 이상 요청 지연과 CPU·메모리 비용은 어떻게 달라졌는가?
- 클라이언트 연결 풀이 만든 평균의 5~10배 동시 요청 편중은 이후 어떤 방식으로 해결됐는가?