요즘 CI 최적화에서 핵심은 “러너 더 붙이기"가 아닙니다. 팀이 실제로 바꾸는 포인트는 빌드가 재현 가능한가(hermetic), 그리고 **이미 계산한 결과를 조직 전체가 재사용하는가(remote cache)**입니다. 특히 모노레포나 다중 서비스 레포에서 PR 수가 늘수록, 같은 작업을 다시 빌드하고 다시 테스트하는 낭비가 누적됩니다. 이때 병목은 컴퓨트 성능이 아니라, 파이프라인 설계와 캐시 신뢰도입니다.

이 글에서 얻는 것

  • Hermetic Build와 일반 캐시를 구분해, 왜 “캐시 적중률"보다 먼저 “재현성"을 맞춰야 하는지 이해할 수 있습니다.
  • Remote Cache를 도입할 때 필요한 실무 기준(적용 대상, 보안 범위, 실패 시 폴백)을 숫자로 정리할 수 있습니다.
  • CI 시간 단축을 단발성 튜닝이 아니라 **운영 지표(리드타임·재실행·적중률)**로 관리하는 방법을 가져갈 수 있습니다.

핵심 개념/이슈

1) Hermetic Build는 빠르게 만드는 기술이 아니라, 같게 만드는 기술이다

Hermetic Build는 “같은 입력이면 어디서 돌려도 같은 산출물"을 목표로 합니다.

핵심 조건은 단순합니다.

  • 의존성 버전 고정(lockfile, digest pin)
  • 빌드 시 외부 네트워크 접근 최소화 또는 통제
  • 시간/로케일/머신 상태 같은 숨은 입력 제거
  • 툴체인 버전 고정(컴파일러, 런타임, 플러그인)

이 조건이 맞지 않으면 remote cache를 붙여도 오히려 불안정해집니다. 어떤 러너에서는 적중되고, 다른 러너에서는 미스가 나면서 “왜 느린지"를 설명하지 못합니다. 이 문제는 Merge Queue + Flaky Quarantine에서 다룬 “신뢰 가능한 통과율” 이슈와 같은 축입니다.

2) Remote Cache의 본질은 저장이 아니라 “중복 계산 제거"다

Remote Cache를 잘 쓰는 팀은 캐시를 파일 저장소가 아니라 계산 결과 저장소로 봅니다.

  • 로컬 캐시: 개발자 개인 반복 작업 가속
  • 원격 캐시: 팀/CI 전체 중복 계산 제거

여기서 중요한 지표는 다음 3개입니다.

  • cache_hit_rate (단, read hit 기준)
  • cache_download_time_ratio (다운로드 시간이 전체의 몇 %인지)
  • rebuild_avoidance_minutes (회피한 빌드 시간)

권장 기준 예시:

  • PR CI 기준 cache_hit_rate < 40%가 2주 지속되면 키 설계 재점검
  • cache_download_time_ratio > 25%면 압축/청크/네트워크 경로 최적화 우선
  • 리포 규모가 큰데 rebuild_avoidance_minutes가 낮다면, 타깃 분할/그래프 의존성 정의가 부정확할 가능성 큼

3) 2026년 흐름: “빌드 그래프 + 테스트 영향 분석 + 캐시 정책"의 결합

최근엔 단일 기법보다 조합 운영이 많습니다.

  1. 변경 파일 기반으로 영향 그래프를 계산하고
  2. 영향받는 타깃만 빌드/테스트하며
  3. 결과를 remote cache로 공유하고
  4. Merge Queue에서 최종 일관성을 검증합니다.

즉 “무조건 전체 테스트"와 “무조건 캐시 신뢰"의 극단을 피하고, 위험도 기반으로 비용을 조절합니다. 이 접근은 PR Risk Scoring + Test Impact Analysis와 결합될 때 운영 난이도가 크게 내려갑니다.

4) 보안 이슈: 캐시 중독(cache poisoning)과 출처 검증

Remote Cache는 편하지만 공급망 면적도 넓힙니다.

  • 악성/오염 산출물 업로드
  • 권한 없는 프로젝트 간 캐시 공유
  • 서명 없는 아티팩트 재사용

그래서 요즘 팀은 다음을 기본값으로 둡니다.

  • 브랜치/프로젝트/권한 경계별 캐시 네임스페이스 분리
  • main 머지용 산출물은 서명/검증 필수
  • PR(외부 기여)에서는 write 권한 제한, read-only 또는 별도 캐시 사용

세부 가이드는 CI/CD 공급망 보안과 함께 보는 게 안전합니다.

실무 적용

1) 적용 대상 판단 기준(숫자·조건·우선순위)

다음 중 2개 이상이면 도입 효과가 큽니다.

  • 활성 기여자 30명 이상
  • PR당 CI 평균 20분 이상
  • 동일 리포에서 하루 PR 40건 이상
  • 재실행(re-run) 비율 15% 이상

우선순위는 재현성 확보 > 캐시 공유 > 공격면 통제 > 미세 최적화 순으로 두는 게 안정적입니다.

2) 3단계 도입 플랜

1단계: Hermetic Baseline (1~2주)

  • lockfile 없는 의존성 차단
  • 빌드 스크립트의 시간/환경 의존 입력 제거
  • 툴체인 버전 강제(예: containerized build)

2단계: Remote Cache 확장 (2~3주)

  • CI read/write, 로컬은 read 우선으로 시작
  • 캐시 키에 OS/아키텍처/컴파일러 버전 포함
  • 적중률·다운로드비율 대시보드 구축

3단계: 정책화 (1주+)

  • 외부 PR write 차단
  • main 릴리스 타깃은 서명 검증 후 배포
  • 캐시 TTL/정리 정책 운영(예: 14~30일)

3) 운영 임계치 예시

  • ci_lead_time_p95 > 45분 3일 지속: 캐시 정책보다 영향 분석 정확도 먼저 점검
  • cache_hit_rate(main) < 60%: 타깃 경계 재설계(과대 invalidation 가능성)
  • cache_poisoning_suspect > 0: 즉시 cache bypass + 아티팩트 재검증
  • rebuild_avoidance_minutes 주간 감소세 2주 연속: 의존성 그래프 드리프트 감사

4) 팀 운영 룰 예시

  • “캐시 미스는 실패가 아니라 신호"로 간주하고 원인을 태깅
  • build graph 변경 PR은 일반 기능 PR과 분리 리뷰
  • 캐시 키 변경은 릴리스 노트에 기록
  • 월 1회 캐시 품질 리뷰(적중률, 오염 사례, 비용)를 정례화

트레이드오프/주의점

  1. 초기에는 작업이 늘어난다
    스크립트 정리, 락파일 정착, 툴체인 고정 등 기반 작업이 필요합니다. 단기 속도보다 기반 신뢰를 먼저 잡아야 합니다.

  2. 적중률 집착은 역효과를 낼 수 있다
    적중률 90%만 쫓다가 잘못된 재사용으로 오류를 키울 수 있습니다. 신뢰도와 보안을 같이 봐야 합니다.

  3. 모든 워크로드를 캐시하면 비용이 늘 수 있다
    짧은 작업까지 원격 캐시에 올리면 저장/전송 비용이 커집니다. 고비용 타깃부터 선별 적용이 낫습니다.

  4. 도구 도입만으로 해결되지 않는다
    Bazel/Nx/Turborepo 같은 도구 선택보다, 의존성 그래프 품질과 팀 규칙이 성패를 좌우합니다.

체크리스트 또는 연습

체크리스트

  • 빌드 입력(의존성/환경/툴체인)이 고정돼 있다.
  • remote cache read/write 권한이 브랜치/주체별로 분리돼 있다.
  • cache hit, download ratio, CI p95 리드타임을 함께 본다.
  • 캐시 오염 대응 런북(bypass, 재빌드, 검증)이 있다.
  • 영향 분석 기반 부분 빌드/부분 테스트가 운영된다.

연습 과제

  1. 최근 2주 CI 로그에서 “동일 커밋 재빌드” 시간을 집계해 rebuild_avoidance_minutes 잠재치를 계산해보세요.
  2. 캐시 키 구성 요소(언어 런타임/OS/아키텍처/컴파일러/환경 변수)를 표로 만들고, 누락 항목을 점검해보세요.
  3. 외부 PR 시나리오를 가정해 read-only 캐시 정책과 main 전용 write 정책을 설계해보세요.

관련 글