선형 엔지니어 Mufeez Amjad는 AI 코딩 에이전트가 CI를 최악의 병목 현상으로 만든 후 회사가 지속적 통합 파이프라인을 어떻게 재작업했는지에 대한 자세한 설명을 발표했습니다. 즉, 풀 요청 대기 시간을 6분 이상에서 5분 남짓으로 단축하고 테스트 스위트는 연초 이후 거의 4배 증가했습니다.
9월 21일 Linear의 엔지니어링 블로그에 게시된 이 게시물은 흔히 그렇듯이 위에서부터 간결한 티켓으로 시작되었습니다. 올해 초 Amjad는 Linear를 열었고 회사의 CTO인 Tuomas가 그에게 "CI 비용이 높습니다"라는 문제를 할당하고 그 동안 CI를 더 빠르게 만들 것을 요청했다는 사실을 알게 되었습니다. 이 이야기에 대한 자세한 내용은 진행 중인 AI 산업 보도를 참조하세요.
에이전트가 유효성 검사를 앞지르는 경우
문제는 구조적인 것이지 우발적인 것이 아닙니다. Amjad는 "에이전트 덕분에 코드 배송 속도가 기하급수적으로 빨라졌지만 이러한 변경 사항을 검증하는 속도는 같은 속도로 유지되지 않았습니다."라고 썼습니다. 모든 끌어오기 요청은 여전히 CI를 통과해야 하므로 개발이 가속화됨에 따라 CI는 관문이 되어 인프라 비용을 높이고 개발자와 에이전트가 피드백을 더 오래 기다리게 만듭니다.
PR이 CI를 기다리는 시간과 소비하는 실행 시간의 두 가지 지표에 대해 선형으로 최적화되었습니다. 수개월 간의 작업 결과: 1월 이후 테스트 스위트가 거의 4배 증가했음에도 불구하고 풀 요청 대기 시간은 6분 이상에서 5분 남짓으로 줄었고 테스트당 실행 시간은 대략 절반으로 줄었습니다.
작업은 인프라 및 도구 업그레이드, 다른 작업의 핵심이 되는 작업 최적화, 반복 설정 감소, 테스트 실행 효율성 향상 등 크게 네 가지 범주로 나뉩니다. Linear의 코드베이스는 주로 TypeScript이지만 많은 최적화가 언어와 툴체인 전반에 걸쳐 적용됩니다.
더 빠른 머신과 네이티브 컴파일러
초기의 이점 중 일부는 CI 자체의 최적화가 거의 필요하지 않았습니다. 더 빠른 CPU, 더 높은 성능의 스토리지, 더 나은 캐시 인프라를 갖춘 GitHub Actions에서 타사 실행기로 워크로드를 이동하면 즉시 성과를 거둘 수 있습니다. 스위치 양쪽에서 이틀 동안 비슷한 비교를 했을 때 작업은 평균 34% 더 빠르게 실행되었으며 'tsc'와 같은 일부 워크로드는 52% 감소했습니다.
툴체인을 현대화하면 승리가 더욱 쉬워졌습니다. 기본 TypeScript 컴파일러인 `tsgo`로 전환하면 유형 검사의 주간 중앙값이 73% 줄었습니다. 이는 유형 검사에서 병목 현상을 완전히 제거할 수 있을 만큼 충분히 큰 것입니다.
타입 그래프 없이 린팅하기
Linting은 또 다른 초기 목표였습니다. Linear의 사용자 정의 ESLint 규칙 중 일부는 TypeScript 유형 정보에 의존하여 모든 Lint 실행이 평가 전에 전체 유형 그래프를 작성하도록 강제하여 Linting을 가장 메모리 집약적인 CI 작업 중 하나로 만들었습니다.
팀은 추상 구문 트리에 대한 정적 분석을 사용하여 유형 정보 없이 함수와 유사한 구성 및 보호 패턴을 식별하는 규칙을 다시 작성했습니다. 이를 통해 ESLint는 TypeScript를 완전히 삭제하여 API 린트 시간을 68%, 전체 저장소 린트 시간을 55% 줄이고 메모리 사용량을 크게 줄였습니다. 또한 나중에 Oxlint로의 마이그레이션이 쉬워졌으며 Linting에 소요되는 CI 실행 시간이 더욱 단축되었습니다.
중요 경로 축소
개별 검사 속도가 빨라짐에 따라 Linear는 CI를 축소하고 시스템으로 처리했습니다. 이는 다른 모든 것 앞에 있는 작은 작업에 주목하게 되었습니다. 경로 변경 감지 및 테스트 결과 캐시는 작업 수준에서 해당 게이트를 확인합니다. 이는 8개의 API 테스트 샤드 중 어느 것도 완료될 때까지 시작할 수 없음을 의미합니다.
수정 사항은 세분화되었지만 추가적이었습니다. 페치 깊이 제한은 가장 느린 게이트를 94초에서 20초로 잡았습니다. 작업 트리가 전혀 필요하지 않은 작업에서 체크아웃을 완전히 제거하면 해당 시간이 27초에서 7초로 줄었습니다. 기록이 제한된 희소하고 얼룩 없는 체크아웃은 푸시 및 병합 대기열 이벤트에 대해 추가로 11초 이상을 절약했습니다. 전체적으로 변경 감지 작업의 평균 지속 시간은 26초에서 8초로, p90은 31초에서 12초로, 가장 느린 실행 시간은 138초에서 37초로 줄었습니다.
체크아웃 안정성에도 작업이 필요했습니다. 타사 실행기가 GitHub 네트워크 외부에 있고 직접 IP 링크에 의존하기 때문에 간헐적인 링크 성능 저하로 인해 가져오기가 가끔 중단됩니다. Linear는 `actions/checkout`을 백오프로 재시도하는 자체 복합 작업으로 대체하고 `GIT_HTTP_LOW_SPEED_LIMIT` 및 `GIT_HTTP_LOW_SPEED_TIME`을 설정하여 정지된 연결이 중단되는 대신 약 30초 후에 중단되도록 하고 고정 디스크에 영구 Git 미러를 유지하는 체크아웃 캐시를 사용합니다.
한 가지 미묘한 수정으로 낭비되는 병합 대기열 시간이 제거되었습니다. 병합 전 최종 검사의 일부로 캐시 마커가 작성되어 PR이 테스트를 통과한 후에도 대기열에 있을 수 있었습니다. 해당 쓰기를 모든 API 풀 요청 및 병합 대기열 항목에 대한 병합 경로에서 42초 단축된 비게이트 작업으로 이동합니다. 이러한 변경 사항으로 인해 실행기 시작을 줄이면서 캐시 누락 시 API PR에 필요한 확인 시간이 약 1분 정도 단축되었습니다.
작업당 낭비되는 시간(초) 감소
마지막 범주는 모든 작업에서 반복되는 설정 비용을 공격했습니다. 각 API 테스트 샤드는 실행될 때마다 apt를 사용하여 동일한 Postgres 클라이언트를 설치하는 데 7~8초가 소요되었습니다. Node와 함께 작은 CI 기본 이미지로 이동하면 샤드 실행 준비가 시작될 수 있습니다. 팀은 나중에 설치 중에 다운로드가 가끔 중단될 수 있다는 사실을 발견한 후 이미지에 기본 빌드 헤더를 추가했습니다.
반향을 불러일으킨 이유
이 게시물은 개발자들에게 큰 충격을 주었습니다. 이 게시물은 Hacker News의 첫 페이지에 올라 하루 만에 약 250포인트와 약 280개의 댓글을 기록했습니다. 반응은 설명하기 쉽습니다. Linear의 경험에 따르면 대부분의 엔지니어링 조직이 현재 직면하고 있는 AI 지원 개발 비용이 지정됩니다. 몇 분 만에 끌어오기 요청을 생성하는 에이전트는 여전히 사람의 흐름에 맞게 설계된 검증 파이프라인을 기다리고 있으며, 해당 대기 시간의 1분은 병렬로 작업하는 모든 에이전트에 곱해집니다.
Linear의 재작업에서 얻은 교훈은 병목 현상이 움직일 수 있지만 단 하나의 만병통치약이 아니라 더 빠른 실행기, 저렴한 유형 검사, 구문 수준 린트 규칙, 제한된 가져오기, 복원력 있는 체크아웃, 사전 구축된 이미지 등 많은 작은 수정 사항이 눈에 띄지 않게 축적되어야만 가능하다는 것입니다.
---
AI보다 앞서 나가세요최신 AI 뉴스, 분석, 획기적인 소식을 모두 한 곳에서 받아보세요.
AI 뉴스 자세히 보기 →