OpenAI, Git 호환 백엔드 Pando로 모노레포 개발 전환
OpenAI는 Codex로 병렬 작업이 늘어난 모노레포에 Git 호환 백엔드 Pando를 도입했습니다. 브랜치별 푸시를 독립 처리하고 저장된 packfile을 재사용해, 회사가 밝힌 중앙값 푸시 지연은 전환 뒤 거의 80% 줄었습니다. 브랜치별 순서는 보장하지만 여러 브랜치 전체의 단일 시점 스냅샷은 제공하지 않습니다.

본문
OpenAI가 Git 클라이언트와 프로토콜을 유지하면서 모노레포 개발의 저장소 백엔드를 Pando로 전환했습니다. OpenAI 기술 스태프 Aaron Friel, Taylor Blau, Ted Nyman은 11월 2일 공개한 기술 글에서 Pando가 현재 OpenAI 모노레포의 모든 개발을 처리한다고 밝혔습니다. Codex로 병렬 작업이 늘며 푸시와 fetch가 함께 증가한 상황에 맞춰 백엔드를 다시 설계한 것으로, OpenAI는 전환 뒤 중앙값 푸시 지연이 거의 80% 줄었고 하루에 거의 1페타바이트의 Git 데이터를 전달한다고 설명했습니다.
Git은 파일 내용과 커밋 이력을 객체로 저장하고, 브랜치는 특정 커밋을 가리키는 참조로 관리합니다. 푸시는 새 객체 묶음인 packfile을 보내면서 브랜치 참조를 갱신합니다. Pando는 이 두 요소를 분리해 packfile은 객체 저장소에, 참조 버전과 packfile의 의존 관계는 메타데이터 서비스에 기록합니다. 두 저장소는 수평 확장을 전제로 설계했습니다.
클라이언트가 푸시하면 Pando는 packfile을 로컬 저장소에 풀지 않고 검증하면서 객체 저장소로 스트리밍합니다. 메타데이터 서비스에는 새 참조 버전을 기록하고 브랜치 포인터를 원자적으로 갱신합니다. 이 과정은 푸시한 클라이언트가 곧바로 자기 변경을 읽는 일관성을 제공합니다. OpenAI는 푸시의 메타데이터 읽기와 쓰기를 상수 횟수로 유지하도록 설계했으며, 매우 큰 푸시는 커밋 일부만 동기적으로 기록해 이 조건을 맞춘다고 설명했습니다.
브랜치별 참조를 독립적으로 관리하는 점이 동시 쓰기의 바탕입니다. 서로 다른 브랜치에 대한 푸시는 한 저장소의 공통 참조 목록을 갱신하기 위해 차례를 기다리지 않습니다. 같은 브랜치에 동시에 푸시가 오면 그 브랜치의 참조를 대상으로 충돌 검사를 합니다. OpenAI가 검토한 복제본 합의 방식이나 공용 쓰기 로그는 저장소 전체에서 쓰기 순서를 맞추는 과정에 의존하므로, 무관한 브랜치의 푸시도 같은 조정 지점에서 경쟁할 수 있습니다.
클라이언트에 어떤 참조를 알릴지도 바꿨습니다. 일반적인 Git 서버는 많은 브랜치 정보를 광고해 클라이언트가 이미 가진 객체를 packfile에서 제외하도록 돕습니다. 하지만 브랜치가 매우 많아지면 참조 목록을 만들고 최신 상태로 유지하는 비용도 커집니다. Pando는 새 기능 브랜치의 기준으로 trunk만 광고합니다. 브랜치가 늘어도 광고 목록이 커지지 않는 대신, 기능 브랜치를 반복해서 푸시하거나 다른 기능 브랜치 위에 쌓을 때 trunk 이후의 객체를 다시 보낼 수 있습니다. OpenAI는 이 방식으로 자사 모노레포에서 생성한 packfile의 중앙값이 20KiB 미만이고 99백분위가 3MiB 미만이었다고 밝혔습니다.
읽기 요청에서 클라이언트는 이미 가진 커밋과 필요한 커밋을 서버에 전달합니다. Pando는 이 haves와 wants를 참조 버전 기록에 연결해 필요한 packfile을 선택합니다. 서버가 각 클라이언트의 요청에 맞춰 새 packfile을 일일이 만드는 대신 저장된 packfile을 재사용합니다. 서버는 packfile URI를 반환하고, 클라이언트는 지역 캐시를 둔 Express 서비스에서 데이터를 내려받습니다. 이렇게 하면 여러 개발 환경과 CI 작업이 같은 이력을 요청할 때에도 서버가 매번 객체를 풀고 다시 묶는 작업을 줄일 수 있습니다.
작은 packfile이 쌓이면 변경 이력을 따라잡을 때 너무 많은 파일을 요청하게 됩니다. Pando는 백그라운드에서 packfile을 여러 단계의 큰 묶음으로 합칩니다. 이 compaction은 fetch 때 필요한 묶음을 찾는 일을 빠르게 하고, 전송할 데이터 양도 줄입니다. Pando는 기존 단계의 packfile도 계속 유지해 클라이언트가 가진 이력에 따라 적절한 묶음을 제공한다고 설명했습니다.
이 설계에는 일관성의 조건이 따릅니다. Pando는 각 브랜치 안의 변경 순서를 보장하지만, 여러 브랜치를 읽을 때 저장소 전체가 같은 시점의 상태라고 보장하지 않습니다. 예를 들어 여러 브랜치가 동시에 갱신되면 한 클라이언트가 읽은 브랜치별 버전의 조합과 다른 클라이언트가 읽은 조합이 다를 수 있습니다. OpenAI는 개발자와 에이전트가 주로 각 브랜치의 변경 순서에 의존하며 저장소 전체 참조의 단일 시점 순서에는 의존하지 않는다고 설명했습니다.
OpenAI는 종전 시스템과 Pando를 읽기·쓰기 프록시로 연결해 동기화한 뒤 트래픽을 단계적으로 옮겼습니다. Codex로 병렬 작업이 늘면서 브랜치 푸시와 병합뿐 아니라 개발 환경과 CI의 fetch·clone도 증가했고, 종전 시스템은 느린 요청과 병합 실패를 겪었습니다. OpenAI는 Pando 전환 뒤 중앙값 푸시 지연이 거의 80% 낮아지고 병합 신뢰성도 개선됐다고 보고했습니다. 하루 데이터 전송량은 거의 1페타바이트라고 밝혔습니다.
Pando는 새 명령 체계를 도입하는 도구가 아니라 기존 Git 작업 흐름을 유지하는 백엔드입니다. OpenAI는 이 시스템을 만들며 packfile URI 다운로드의 중단 복구와 재개, 병렬 packfile 다운로드 같은 Git 클라이언트 개선도 진행해 공개 Git에 기여했다고 설명했습니다. Pando의 확장 방식과 함께 Git 자체의 packfile 처리도 손봤다는 점에서 이번 설계는 서버와 클라이언트 양쪽의 변경으로 이뤄졌습니다.
자료: OpenAI Engineering / 정리·해설: Trawling