게임 빌드 파이프라인 대기 시간과 실행 시간 분리로 릴리즈 Lead Time 병목 찾기

게임 빌드 파이프라인의 큐 대기 시간과 실제 실행 시간을 분리해 측정하고 p95와 재시도율로 릴리즈 Lead Time 병목을 찾아 개선하는 실무 방법을 정리합니다.

✓ 복사 완료!
챕터빌드 자동화 & CI/CD
난이도중급
상태● 검토 완료
대상 엔진
Engine Agnostic
최종 업데이트
게임 빌드 파이프라인 대기 시간과 실행 시간 분리로 릴리즈 Lead Time 병목 찾기

핵심 요약

릴리즈 Lead Time 병목을 찾으려면 각 빌드 단계의 전체 소요 시간을 하나의 값으로 보지 말고 대기 시간(queue wait)과 실행 시간(execution)으로 분리해야 합니다. 대기 시간이 길면 러너 수, 동시성, 우선순위 정책을 점검하고 실행 시간이 길면 캐시, 병렬화, 에셋 처리와 테스트 자체를 최적화해야 합니다.

단계별 p50·p95·최대값과 재시도율을 수집한 뒤 실제 릴리즈 경로의 임계 경로(critical path)에 기여하는 시간을 기준으로 우선순위를 정하면 감이 아닌 데이터로 병목을 개선할 수 있습니다.

왜 빌드 파이프라인의 Lead Time을 분리해서 봐야 하는가?

게임 팀에서 “빌드가 오래 걸린다”는 말은 서로 다른 문제를 한 문장으로 표현하는 경우가 많습니다.

  • 빌드가 시작되기 전 CI 러너를 기다리는 문제
  • Unity 에셋 임포트나 셰이더 컴파일이 느린 문제
  • 테스트 실패 후 재시도하는 문제
  • 패키징은 끝났지만 업로드나 배포 승인을 기다리는 문제

예를 들어 전체 빌드 시간이 30분이라고 해도 실제 실행은 12분이고 나머지 18분은 러너를 기다리는 시간일 수 있습니다. 이 경우 코드나 에셋을 최적화해도 릴리즈 Lead Time은 크게 줄지 않습니다.

파이프라인의 기본 시간은 다음처럼 정의할 수 있습니다.

Lead Time=Queue Wait Time+Execution Time+Retry DelayLead\ Time = Queue\ Wait\ Time + Execution\ Time + Retry\ Delay

여기서 Queue Wait Time은 작업이 생성된 시점부터 실행기가 작업을 시작한 시점까지의 시간입니다. Execution Time은 실제 명령이 실행된 시간이며 Retry Delay는 실패 후 재시작하거나 승인 대기 때문에 추가된 시간입니다.

빌드 단계별로 어떤 시간을 기록해야 하는가?

먼저 릴리즈 범위를 명확히 정해야 합니다. 예를 들어 GitHub Actions에서 Unity 2022.3 LTS 빌드가 시작되는 시점부터 플랫폼별 아티팩트가 저장되는 시점까지를 측정할 수 있습니다. 배포까지 포함한다면 업로드와 스토어 제출 단계도 같은 추적 ID로 연결해야 합니다.

구분측정 시작측정 종료확인할 병목
큐 대기작업 생성러너 할당러너 부족, 동시성 제한
소스 준비러너 시작체크아웃 완료저장소 크기, 네트워크
의존성 복원복원 시작복원 완료패키지 서버, 캐시 적중률
에셋 임포트임포트 시작임포트 완료Library 캐시, 임포트 설정
컴파일컴파일 시작컴파일 완료스크립트 구조, 코드 생성
테스트테스트 시작테스트 완료테스트 수, 불안정 테스트
콘텐츠 빌드빌드 시작데이터 생성 완료Addressables, 셰이더, 번들 분할
패키징패키징 시작설치 패키지 생성압축, 서명, 플랫폼 도구
업로드·배포업로드 시작배포 완료저장소, 승인, 배포 슬롯

각 단계에는 최소한 다음 필드를 남기는 것이 좋습니다.

{
  "pipeline_id": "release-2026-08-29-001",
  "stage": "unity-content-build",
  "queued_at": "2026-08-29T09:00:00Z",
  "started_at": "2026-08-29T09:07:30Z",
  "finished_at": "2026-08-29T09:19:10Z",
  "status": "success",
  "retry_count": 0,
  "runner_type": "windows-large",
  "cache_hit": true,
  "commit_sha": "abc1234"
}

이 데이터에서 대기 시간은 started_at - queued_at으로 계산하고 실행 시간은 finished_at - started_at으로 계산합니다. 시간대가 다른 여러 시스템을 연결한다면 모든 로그를 UTC로 저장하고 화면에 표시할 때만 현지 시간으로 변환해야 합니다.

릴리즈 Lead Time 병목은 어떻게 계산하는가?

1. 단계별 대기 시간과 실행 시간을 계산한다

각 단계에 대해 다음 값을 계산합니다.

Queue Wait=Started At−Queued AtQueue\ Wait = Started\ At - Queued\ At Execution Time=Finished At−Started AtExecution\ Time = Finished\ At - Started\ At

단순 평균만 사용하면 긴 꼬리를 놓치기 쉽습니다. 최소한 p50과 p95를 함께 봐야 합니다.

지표의미PM 관점의 활용
p50일반적인 빌드의 소요 시간평상시 개발 흐름 파악
p95느린 빌드의 상한에 가까운 값릴리즈 일정 리스크 파악
최대값최악의 사례장애와 특이 상황 조사
재시도율실패 후 다시 실행된 비율숨은 지연과 품질 문제 파악
캐시 적중률캐시가 사용된 비율캐시 정책의 효과 확인

2. 병렬 단계는 합산하지 말고 임계 경로를 계산한다

플랫폼별 빌드가 동시에 실행된다면 모든 실행 시간을 더하면 안 됩니다. Android, Windows, PlayStation 빌드가 병렬로 수행되는 경우 릴리즈를 막는 시간은 가장 늦게 끝난 경로에 가깝습니다.

릴리즈 준비
├─ Android 빌드: 18분
├─ Windows 빌드: 24분
└─ 콘솔 빌드: 41분  ← 임계 경로

위 사례의 플랫폼 빌드 구간은 83분이 아니라 약 41분으로 봐야 합니다. 다만 공통 사전 단계와 후속 업로드 단계가 있다면 전체 Lead Time은 다음처럼 계산합니다.

Total Lead Time=Common Stages+Max(Parallel Branches)+Post Release StagesTotal\ Lead\ Time = Common\ Stages + Max(Parallel\ Branches) + Post\ Release\ Stages

단계별 병목 기여도를 비교할 때는 임계 경로에 포함된 시간만 우선순위에 반영합니다.

3. 병목 기여도를 기준으로 개선 순위를 정한다

단계별 기여도는 다음과 같이 정의할 수 있습니다.

Bottleneck Contribution=Critical Path Time×Retry FactorBottleneck\ Contribution = Critical\ Path\ Time \times Retry\ Factor

Retry Factor는 재시도로 인한 추가 지연을 반영하기 위한 팀 내부 지표입니다. 단순하게 계산하려면 성공한 실행 시간과 실패 후 재실행에 걸린 시간을 별도 집계하면 됩니다.

예를 들어 다음과 같이 해석할 수 있습니다.

관측 결과가능성이 높은 원인우선 조치
대기 p95가 높고 실행 p50는 낮음러너 부족, 동시성 제한러너 풀과 예약 정책 점검
대기 p50와 p95가 모두 낮고 실행 시간이 높음단계 자체가 느림캐시, 병렬화, 작업량 개선
평균은 낮지만 p95가 매우 높음특정 브랜치나 에셋에서 긴 꼬리 발생느린 사례의 메타데이터 비교
실행 시간과 재시도율이 모두 높음불안정 테스트, 리소스 부족실패 원인과 재시도 정책 분석
빌드는 빠르지만 배포 완료가 늦음승인 또는 업로드 병목배포 프로세스와 책임자 명확화

대기 시간과 실행 시간을 어떻게 계측할까?

Step 1. 시작점과 종료점을 합의한다

팀마다 Lead Time의 시작점이 다르면 지표를 비교할 수 없습니다. 다음 중 하나를 기준으로 고정합니다.

  1. 코드가 기본 브랜치에 병합된 시점부터 테스트 배포 완료까지
  2. 릴리즈 브랜치가 생성된 시점부터 최종 아티팩트 생성까지
  3. CI 작업이 등록된 시점부터 운영 환경 배포 완료까지

게임 제작팀의 스프린트 계획이나 릴리즈 회고에서는 보통 “릴리즈 후보가 준비된 시점부터 테스트 가능한 빌드가 배포된 시점”처럼 실제 의사결정 단위와 연결하는 편이 유용합니다.

Step 2. 모든 단계에 공통 이벤트를 추가한다

CI 도구가 GitHub Actions인지 Jenkins인지와 관계없이 단계 이벤트의 이름과 필드는 통일해야 합니다.

stage.queued
stage.started
stage.finished
stage.failed
stage.retried

이벤트에는 pipeline_id, stage, commit_sha, platform, runner_type, cache_hit, status를 포함합니다. Unity 빌드라면 unity_version, build_target, development_build, addressables_profile도 함께 기록하면 원인 분석에 도움이 됩니다.

예를 들어 같은 콘텐츠 빌드라도 Unity 2022.3.40f1, Windows, Release, Addressables-Production 조합과 Development 조합은 실행 시간이 다를 수 있습니다. 메타데이터가 없으면 실행 시간이 증가한 이유를 코드 변경 때문인지 빌드 설정 때문인지 구분하기 어렵습니다.

Step 3. 대시보드에서 p95와 임계 경로를 확인한다

대시보드는 전체 평균 하나보다 다음 화면을 우선 제공해야 합니다.

  • 단계별 Queue Wait p50·p95
  • 단계별 Execution Time p50·p95
  • 플랫폼별 임계 경로
  • 캐시 적중률
  • 재시도율과 실패 원인
  • 최근 커밋 또는 에셋 변경과 시간 증가의 관계

시간을 매일 기록해도 한 번의 느린 빌드만으로 결론을 내리면 안 됩니다. 최소한 동일한 브랜치, 플랫폼, 빌드 설정을 기준으로 최근 여러 릴리즈를 비교하고 변경 전후의 분포를 확인해야 합니다.

대기 시간이 길 때 무엇을 개선해야 하는가?

대기 시간은 실행 작업이 시작되기 전의 시스템 문제입니다. 실행 명령을 최적화하기 전에 다음 항목을 확인합니다.

러너와 동시성 제한

동시에 실행할 수 있는 작업 수보다 요청이 많으면 큐가 길어집니다. 플랫폼별 러너 풀을 분리하면 콘솔 빌드가 일반 클라이언트 빌드를 막는 현상을 줄일 수 있습니다.

다만 러너 수를 무조건 늘리는 것은 비용과 관리 복잡도를 키울 수 있습니다. 먼저 다음을 확인합니다.

  • 업무 시간에만 큐가 증가하는가?
  • 특정 플랫폼 러너만 부족한가?
  • 동일 커밋의 중복 빌드가 많은가?
  • Pull Request 검증과 릴리즈 빌드가 같은 큐를 사용하는가?
  • 낮은 우선순위의 야간 빌드가 릴리즈 빌드를 막는가?

우선순위와 취소 정책

같은 브랜치에 새 커밋이 들어오면 이전의 오래된 검증 빌드를 취소할 수 있습니다. 반면 릴리즈 후보나 핫픽스 빌드는 별도의 높은 우선순위 큐로 보내야 합니다.

PM은 이 정책을 기술 설정으로만 남기지 말고 문서화해야 합니다. “릴리즈 브랜치는 최대 두 개의 동시 작업을 예약한다”, “같은 PR의 이전 검증 빌드는 새 커밋이 생성되면 취소한다”처럼 팀이 예측할 수 있는 규칙으로 적어야 합니다.

실행 시간이 길 때 무엇을 개선해야 하는가?

실행 시간이 길다는 것은 러너가 실제로 작업을 수행하는 데 오래 걸린다는 의미입니다. 다음 순서로 접근하면 스코프를 통제하기 쉽습니다.

  1. 가장 긴 단계가 전체 임계 경로에 포함되는지 확인합니다.
  2. 해당 단계의 작업을 다운로드, CPU, 디스크, 네트워크 구간으로 나눕니다.
  3. 캐시 적중 여부와 캐시 무효화 원인을 확인합니다.
  4. 독립적인 작업을 병렬화하되 러너 대기 시간을 다시 측정합니다.
  5. 빌드 결과와 품질이 유지되는지 검증합니다.

Unity 프로젝트에서는 Library 캐시, Package Manager 캐시, Addressables 번들 캐시와 셰이더 캐시가 주요 관찰 대상입니다. 캐시는 실행 시간을 줄일 수 있지만 잘못 공유하면 오래된 아티팩트가 사용되거나 캐시 무효화 때마다 전체 임포트가 발생할 수 있습니다.

또한 모든 플랫폼을 모든 커밋에서 패키징할 필요가 있는지 확인해야 합니다. 예를 들어 PR에서는 빠른 단위 테스트와 콘텐츠 검증만 수행하고 릴리즈 브랜치에서 전체 플랫폼 패키징을 수행하는 식으로 검증 범위를 나눌 수 있습니다. 이는 품질 기준을 낮추는 것이 아니라 변경 단계에 맞춰 검증 비용을 배치하는 운영 결정입니다.

병목 개선 우선순위는 어떻게 정하는가?

개선 후보는 시간 절감 가능성만으로 결정하지 않습니다. 다음 네 가지를 함께 평가합니다.

평가 항목질문
영향도임계 경로 시간을 실제로 줄이는가?
빈도매 빌드마다 발생하는가?
안정성재시도와 실패를 줄이는가?
비용러너 증설이나 저장 공간 비용이 필요한가?

예를 들어 실행 시간을 10분 줄일 수 있는 최적화라도 야간에 한 번만 실행되는 패키징 단계라면 우선순위가 낮을 수 있습니다. 반대로 2분만 줄여도 하루 수십 번 발생하는 PR 검증 단계라면 개발 흐름에 더 큰 효과를 줄 수 있습니다.

개선 후에는 “빌드가 빨라졌다”가 아니라 다음처럼 목표를 기록하는 것이 좋습니다.

  • 릴리즈 파이프라인 p95 Lead Time을 45분에서 30분 이하로 낮춘다.
  • 큐 대기 p95를 10분 이하로 유지한다.
  • 전체 빌드 재시도율을 8%에서 3% 이하로 낮춘다.
  • Unity 콘텐츠 빌드의 캐시 적중률을 70% 이상으로 유지한다.

팀 운영과 문서화에 어떻게 연결할까?

측정 결과를 기술팀만 보는 지표로 만들면 우선순위 조정에 활용하기 어렵습니다. 릴리즈 회고에는 다음 내용을 함께 기록합니다.

  • 이번 릴리즈의 임계 경로는 어느 플랫폼이었는가?
  • 가장 큰 대기 병목과 실행 병목은 무엇이었는가?
  • 병목이 일정에 미친 실제 영향은 얼마였는가?
  • 다음 스프린트에서 해결할 문제와 보류할 문제는 무엇인가?
  • 개선 작업이 기능 스코프와 충돌할 경우 어떤 기준으로 선택할 것인가?

특히 파이프라인 개선을 별도 기술 부채 목록으로만 관리하지 말고 릴리즈 계획의 리스크 항목으로 연결해야 합니다. p95 대기 시간이 계속 증가한다면 해당 문제는 개발자 편의가 아니라 일정 예측 가능성과 릴리즈 안정성에 영향을 주는 계획 이슈입니다.

자주 묻는 질문 (FAQ)

평균 시간만 보면 안 되는 이유는 무엇인가?

평균은 일부 매우 느린 빌드의 영향을 약하게 보여줍니다. 실제 릴리즈 지연을 파악하려면 일반적인 실행을 나타내는 p50과 느린 사례를 나타내는 p95를 함께 봐야 합니다.

병렬 빌드의 시간은 어떻게 합산해야 하는가?

병렬 브랜치는 모든 시간을 더하지 않고 가장 늦게 끝나는 브랜치를 기준으로 계산합니다. 공통 단계와 후속 단계를 더한 뒤 공통 단계 + 병렬 브랜치 중 최댓값 + 후속 단계로 임계 경로를 구합니다.

러너를 늘리면 Lead Time이 항상 줄어드는가?

아닙니다. 대기 시간이 주된 병목일 때만 효과가 큽니다. 실행 시간이 길거나 캐시가 불안정하거나 재시도율이 높다면 러너 증설보다 단계 최적화와 실패 원인 제거가 먼저일 수 있습니다.

정리

릴리즈 Lead Time을 개선하는 첫 단계는 빌드 시간을 줄이는 것이 아니라 시간을 올바르게 나누어 보는 것입니다. 각 단계에서 queued_at, started_at, finished_at을 기록하고 대기 시간, 실행 시간, 재시도 지연을 분리하면 병목의 종류가 드러납니다.

그 다음 p50·p95와 임계 경로를 기준으로 병목을 우선순위화하고 러너·동시성·우선순위 문제와 캐시·병렬화·에셋 처리 문제를 구분해 개선합니다. 이 데이터를 릴리즈 계획과 회고에 연결하면 빌드 파이프라인은 개발팀의 감각적인 불편 사항이 아니라 일정과 스코프를 관리하는 운영 지표가 됩니다.