GitHub Copilot Rust 재작성 사례를 보고도 팀이 곧바로 전체 런타임을 Rust로 바꾸면 안 됩니다. 시작, 메모리, 임베딩 또는 언어 간 호출에서 반복되는 병목이 측정되고, 모듈 경계와 종단 간 테스트, 점진 배포 체계까지 갖춘 팀만 단일 모듈 시범 이전을 시작하는 편이 안전합니다.

이 글은 대형 TypeScript·Node.js 런타임을 운영하면서 시작 시간과 자원 점유 문제를 겪는 아키텍처 팀을 위한 내용입니다. 여러 AI Coding Agent를 병렬로 투입하려는 플랫폼 엔지니어, Linux·Windows·macOS와 Apple 도구 체인을 함께 검증해야 하는 전달 책임자도 대상입니다.

마지막 업데이트: 2026년 9월 18일. GitHub 공식 엔지니어링 글, Copilot SDK 저장소, GitHub Docs와 변경 기록을 대조해 내용을 확인했습니다.

GitHub Copilot Rust 재작성의 실제 출발점

이번 사례의 핵심은 “TypeScript보다 Rust가 무조건 빠르다”가 아닙니다. GitHub의 Copilot Agent 런타임은 원래 TypeScript, Node.js, V8 위에서 실행됐고, CLI와 여러 제품 및 SDK가 같은 런타임을 공유했습니다. 이 구조에서는 애플리케이션 안에 런타임을 직접 넣기보다 별도 프로세스로 실행하고 JSON-RPC로 통신하는 방식이 사용됐습니다.

GitHub가 설명한 병목은 다음과 같습니다.

  • SDK를 시작할 때 Node.js와 V8을 함께 실행해야 했습니다.
  • 각 이벤트와 메시지가 프로세스 경계를 통과했습니다.
  • 여러 SDK가 필요하지 않은 JavaScript 런타임까지 함께 부담했습니다.
  • 공유 런타임을 여러 세션이 사용할 때 메모리와 CPU 밀도가 문제가 됐습니다.
  • TypeScript 기반 CLI, 런타임, SDK 계층이 초기에 충분히 분리되지 않았습니다.

GitHub는 사전 구현이 약 130,000줄의 TypeScript로 보였지만, 이전 과정에서 실제 대상은 약 430,000줄의 운영 TypeScript로 커졌다고 설명했습니다. 최종적으로는 832,378줄의 운영 Rust와 468,689줄의 Rust 단위 테스트, 174,675줄의 TypeScript 종단 간 테스트를 유지했습니다. 이 수치는 일반 팀의 예상치가 아니라 GitHub의 저장소와 내부 작업 방식에 속한 사례입니다. GitHub의 공식 이전 회고에서도 이 범위를 확인할 수 있습니다.

따라서 첫 판단은 간단합니다. 현재 시스템이 단순히 “느리다”가 아니라 런타임 시작, 프로세스 통신, 상주 메모리, 임베딩 방식 중 어디에서 비용을 내는지 설명하지 못한다면 이전을 시작하지 않는 것이 맞습니다.

성능 지표와 구조 경계

성능 이전에서 가장 흔한 오류는 업무 코드의 느린 쿼리와 런타임 자체의 비용을 같은 문제로 취급하는 것입니다. 데이터베이스 호출, 네트워크 대기, 외부 API 응답이 원인이라면 Rust로 바꿔도 핵심 지연은 그대로 남습니다.

반대로 다음 조건이라면 런타임 이전을 검토할 가치가 있습니다.

  1. 짧은 작업을 반복 실행할 때 프로세스 시작 비용이 전체 시간에서 큰 비중을 차지합니다.
  2. 여러 Agent 세션이 동시에 실행되면서 Node.js와 V8의 메모리 비용이 누적됩니다.
  3. SDK가 런타임을 별도 프로세스로 실행해 이벤트와 파일 시스템 호출을 계속 직렬화합니다.
  4. 여러 언어의 호스트 애플리케이션에 같은 런타임을 직접 삽입해야 합니다.
  5. CPU 사용량이나 프로세스 수가 동시 세션 수를 제한합니다.

GitHub는 고정된 로컬 모델 응답을 사용해 모델 추론과 네트워크 지연을 제거한 뒤, 사전 구현과 Rust 구현을 비교했습니다. 클라이언트 생성부터 세션 한 번의 실행과 종료까지 걸린 시간은 5.25초에서 프로세스 내부 Rust 실행 기준 55.3밀리초로 줄었고, 세션 처리량은 초당 7.55회에서 120회로 늘었습니다. 열 개 클라이언트의 추가 상주 메모리는 1,383 MB에서 프로세스 내부 Rust 기준 126 MB로 감소했습니다. GitHub도 이 결과가 특정 작업 부하의 측정치이며 모든 시스템에 적용되는 보편적인 배수는 아니라고 명시합니다. GitHub의 공식 이전 회고

측정 축 이전을 검토할 신호 바로 이전하지 말아야 할 신호
시작 시간 짧은 작업마다 런타임 생성 비용이 반복됨 실제 지연 대부분이 외부 API와 데이터베이스에서 발생함
메모리 병렬 세션 수가 상주 메모리 때문에 제한됨 메모리 증가 원인이 캐시와 애플리케이션 객체임
통신 프로세스 간 호출과 직렬화가 빈번함 이미 단일 프로세스이며 호출 비용이 작음
처리량 실행기와 CPU 포화가 관측됨 모델 응답 대기가 전체 시간의 대부분임
임베딩 여러 언어 호스트가 같은 엔진을 직접 사용해야 함 Node.js 의존성이 제품 요구와 충돌하지 않음

구조 경계도 같은 수준으로 중요합니다. 터미널 화면, 업무 로직, Agent 반복 실행, 상태 관리, SDK 인터페이스가 하나의 모듈에 섞여 있으면 AI Agent를 여러 개 투입해도 속도가 빨라지지 않습니다. 오히려 요구 사항이 달라지고, 상태 오류가 늘고, 되돌릴 코드 범위가 커집니다.

GitHub는 먼저 화면 계층과 런타임을 분리하고, 순수 로직과 부작용이 적은 요소부터 이전했습니다. 공개 인터페이스를 만들지 않은 채 세션 조정 계층부터 Rust로 옮기면, 상태 소유권과 콜백, 도구 호출, 오류 복구를 동시에 다시 설계해야 합니다. AI Agent는 경계가 없는 시스템에 경계를 만들어 주지 않습니다.

테스트 증거와 배포 경로

AI가 만든 Rust 코드가 컴파일된다는 사실은 기존 TypeScript와 동작이 같다는 뜻이 아닙니다. 언어가 바뀌면 다음 차이가 나타날 수 있습니다.

  • 비동기 대기 방식과 취소 시점이 달라집니다.
  • 공유 상태의 수명과 소유권이 달라집니다.
  • JSON 파싱과 잘못된 입력 처리 방식이 달라집니다.
  • npm 패키지 하나가 여러 Rust 크레이트로 대체될 수 있습니다.
  • 파일, 권한, 프로세스 종료 동작이 플랫폼별로 달라질 수 있습니다.

GitHub의 회고에서도 기능 오류와 성능 저하가 모두 발생했습니다. 특히 Rust와 TypeScript 사이의 직렬화, 잠금, 폴링, 네이티브 호출 경계가 새로운 비용을 만들 수 있다고 설명합니다. GitHub Copilot SDK 저장소는 현재 TypeScript, Python, Go, .NET, Java, Rust용 SDK를 제공하며, SDK와 CLI 사이의 JSON-RPC 구조와 프로세스 실행 방식도 공개하고 있습니다.

검증 계층 저장해야 할 증거 합격 기준
단위 테스트 같은 입력과 출력, 오류 유형 핵심 함수의 결과와 실패 조건이 일치함
프로토콜 테스트 요청, 응답, 이벤트 순서 필드 누락과 순서 변경이 없음
종단 간 테스트 대표 업무 시나리오와 도구 호출 실제 작업 흐름이 중단 없이 완료됨
회귀 비교 이전 구현과 새 구현의 차이 기록 차이가 설명 가능하고 승인됨
플랫폼 테스트 Linux, Windows, macOS 결과 운영 대상 플랫폼에서 동일한 릴리스 조건을 충족함

GitHub는 이전 중 기존 종단 간 테스트를 계속 실행했고, 테스트를 통과하지 못한 변경은 합치지 않았습니다. 또한 이전 기간 동안 128개의 이전 관련 변경을 주 저장소에 합치고, 약 14.5주 동안 135개의 릴리스를 배포했습니다. 이 방식 덕분에 문제가 발생했을 때 최근에 바뀐 컴포넌트와 오류를 연결하기 쉬웠습니다. GitHub의 공식 이전 회고

우리 팀이 적용할 때는 각 이전 모듈마다 다음 네 가지를 남겨야 합니다.

  1. 이전 구현의 기준선 결과입니다.
  2. AI Agent가 생성하거나 수정한 파일 목록입니다.
  3. 새 구현과 기존 구현의 차이 결과입니다.
  4. 사람이 검토하고 승인한 판단 기록입니다.

이 기록이 없다면 실패 원인을 모델, Rust 코드, 실행기, 플랫폼 환경 중 어디에서 찾아야 할지 알 수 없습니다.

점진 이전과 병렬 운영의 선택

대형 프로젝트의 이전 경로는 세 가지로 나눌 수 있습니다.

  • 일괄 재작성: 새 Rust 런타임을 별도 브랜치에서 만든 뒤 한 번에 교체합니다.
  • 장기 이중 운영: TypeScript와 Rust 구현을 동시에 유지하고 결과를 비교합니다.
  • 컴포넌트 단위 교체: 작은 기능부터 Rust로 바꾸고 기존 코드와 연결한 뒤 순서대로 제거합니다.

활발히 변경되는 저장소에서는 세 번째 방식이 대체로 유리합니다. GitHub도 각 변경에서 TypeScript 구현을 얇은 연결 코드로 바꾸고 Rust 구현을 즉시 실행하는 방식을 택했습니다. 주 저장소를 계속 배포 가능한 상태로 유지하고, 변경 범위를 작게 만들어 검토와 원인 추적을 쉽게 한 것입니다.

다만 이중 운영이 항상 더 안전한 것은 아닙니다. 상태를 소유한 세션 조정 계층처럼 여러 모듈에 연결된 기능은 두 구현을 동시에 실행하고 결과를 비교하기 어렵습니다. 상태가 두 곳에서 바뀌고 콜백이 양방향으로 흐르면, 비교를 위한 구조가 실제 운영 복잡성을 키울 수 있습니다.

조건별 결정 목록

  • 성능 기준선이 있고, 모듈이 무상태에 가깝고, 회귀 테스트가 있으며, 이전 버전을 즉시 복구할 수 있다면 단일 모듈 시범 이전을 선택합니다.
  • 성능 기준선은 있지만 테스트 또는 복구 절차가 약하다면 Rust 이전을 확대하지 말고 TypeScript와 Rust의 제한된 이중 운영을 준비합니다.
  • 구조가 얽혀 있고 공개 인터페이스가 없다면 먼저 화면, 업무 로직, Agent 반복 실행, 상태 관리, SDK를 분리합니다.
  • Linux에서는 통과하지만 macOS 네이티브 의존성 검증이 없다면 공통 로직만 병렬 처리하고 맥 검증은 별도 실행 환경으로 분리합니다.
  • 동시 Agent 수만 늘리고 컴파일·테스트 대기열을 측정하지 않았다면 실행 용량을 늘리지 않습니다.
  • 유명 사례와 코드 줄 수만으로 이전을 주장한다면 이전을 보류합니다.

여기서 모델의 코드 생성 속도와 실제 실행 용량을 분리해야 합니다. 모델은 Rust 파일을 빠르게 만들 수 있지만, Agent 작업 공간이 늘어나면 저장소 충돌과 재기반 작업도 늘어납니다. 컴파일 및 테스트 실행기는 별도의 CPU와 메모리를 사용하고, 실제 Mac 검증 환경은 또 다른 병목이 될 수 있습니다.

GitHub Copilot 공식 Agent 동작 설명에 따르면 Agent는 파일 수정과 명령 실행을 수행할 수 있지만, 생성 결과를 사람이 검토하고 검증해야 합니다. 따라서 Agent 수를 늘리는 결정은 모델 응답 시간이 아니라 작업 공간 충돌률, 실행기 대기 시간, 사람의 검토 처리량을 함께 보고 내려야 합니다.

Linux 병렬 풀과 독립 Mac 검증

공통 Rust 라이브러리, 순수 파서, 상태가 없는 변환기는 Linux 격리 환경에서 병렬로 처리하기 쉽습니다. 반면 다음 항목은 macOS에서 별도 검증해야 합니다.

  • macOS 전용 네이티브 라이브러리
  • Apple 도구 체인과 링커
  • 서명과 패키징
  • 파일 권한과 키체인 접근
  • 네이티브 모듈의 컴파일
  • 실제 Mac 클라이언트와의 통신

GitHub Copilot SDK의 Rust 안내 문서도 프로세스 외부 실행과 프로세스 내부 실행을 구분하고, 실행 파일과 네이티브 런타임을 빌드 및 배포 방식에 맞게 함께 제공해야 한다고 설명합니다. 특히 기본 번들 기능을 끄면 배포 환경에서 런타임을 별도로 공급해야 하므로, 개발 머신에서만 성공한 빌드를 그대로 배포해서는 안 됩니다. Rust SDK의 공식 빌드 및 런타임 안내를 배포 설계 전에 확인해야 합니다.

실행 순서는 다음처럼 나누는 것이 좋습니다.

  1. 모델이 생성한 Rust 변경을 Agent 작업 공간별로 분리합니다.
  2. 각 작업 공간에서 형식 검사와 정적 검사를 먼저 실행합니다.
  3. 공통 Linux 실행기에서 단위 테스트와 프로토콜 테스트를 병렬 처리합니다.
  4. 종단 간 테스트를 별도 대기열에 넣어 기준선과 결과를 비교합니다.
  5. macOS 관련 빌드와 네이티브 검증은 독립된 맥 환경에서 재실행합니다.
  6. 실패하면 변경 코드, 실행기, 플랫폼 환경을 구분해 원인을 기록합니다.
  7. 모든 조건을 통과한 뒤에만 다음 컴포넌트로 이전합니다.

GitHub Copilot CLI가 네이티브 Rust 런타임을 사용하고 터미널 계층은 TypeScript로 남아 있다는 공식 변경 기록도 이 계층 분리를 보여 줍니다. 런타임 전체를 한 번에 Rust로 바꾼 것이 아니라, 실행 엔진과 사용자 인터페이스의 책임을 구분한 것입니다. GitHub Copilot 공식 변경 기록도 이 범위를 확인합니다.

일반 팀을 위한 최종 판정

GitHub Copilot Rust 재작성 사례에서 가져와야 할 것은 “우리도 수십만 줄을 다시 쓰자”는 결론이 아닙니다. 가져와야 할 것은 병목을 측정하고, 경계를 먼저 만들고, 테스트 가능한 작은 단위로 교체하며, 실제 사용 환경에서 점진적으로 확인한 절차입니다.

우리라면 다음 순서로 결정합니다.

  1. 성능: 시작, 메모리, 처리량, 프로세스 통신 중 하나가 반복적인 병목인지 측정합니다.
  2. 구조: 공개 인터페이스와 상태 소유권이 분리돼 있는지 확인합니다.
  3. 테스트: 단위, 프로토콜, 종단 간, 대표 업무, 플랫폼 테스트를 준비합니다.
  4. 배포: 작은 변경을 합치고, 중지 조건과 이전 버전 복구 경로를 정의합니다.
  5. 실행 환경: Agent 작업 공간, 컴파일·테스트 실행기, Linux 병렬 풀, 실제 Mac 검증 환경을 따로 계산합니다.

다섯 항목이 모두 준비됐다면 의존성이 적고 상태가 작은 모듈 하나를 골라 시범 이전을 시작합니다. 테스트나 복구 능력이 부족하면 두 구현을 제한적으로 유지하면서 기반을 보완합니다. 단지 GitHub의 성공 사례, 코드 줄 수, AI Agent의 생성 속도만으로 움직이는 팀이라면 지금은 이전을 보류하는 편이 합리적입니다.

현재 방식이 Node.js 기반이라도 모든 문제가 해결되지 않는 것은 아니며, 무리한 Rust 이전은 두 언어의 빌드 체인과 테스트 체계를 동시에 운영하게 만듭니다. 특히 Linux에서만 검증하고 macOS 네이티브 단계에서 실패하면, 배포 직전에 원인을 다시 추적해야 합니다. 반대로 단기 이전이나 회귀 검증처럼 실행량이 갑자기 늘어나는 시기에는 고정 장비를 바로 확장하기보다, zekmac의 맥 환경을 임시 검증 용도로 활용해 실제 Mac 빌드와 복구 시간을 먼저 확인한 뒤 장기 운영 규모를 정하는 방식이 더 안전할 수 있습니다. 장기적으로 높은 사용량이 계속되고 물리 장치나 상시 전용 연결이 필요하다면 직접 장비를 운영하는 편이 맞지만, 이전 초기의 변동성 높은 테스트 수요에는 회수 가능한 맥 실행 환경이 더 잘 맞습니다.

다음 행동은 분명합니다. 첫 Rust 이전 모듈을 정한 뒤 기준선 결과를 저장하고, Linux와 Mac에서 같은 검증을 실행하고, 실패 시 되돌릴 수 있는 작은 변경부터 시작해야 합니다.

자주 묻는 질문

GitHub Copilot의 Rust 런타임 재작성 방식을 일반 팀도 따라도 되나요?

그대로 따라 하면 안 됩니다. GitHub는 여러 제품이 하나의 공유 런타임을 사용하고, 프로세스 시작과 메모리, 언어 간 호출 비용이 반복되는 구조였습니다. 일반 팀은 먼저 같은 병목을 측정해야 합니다. 재현 가능한 수치와 분리된 모듈, 안정적인 회귀 테스트가 없다면 Rust 이전보다 구조 개선이 우선입니다.

AI Agent로 TypeScript 프로젝트를 Rust로 옮길 때 가장 큰 위험은 무엇인가요?

컴파일 성공을 동작 동일성으로 착각하는 것이 가장 큽니다. Rust와 TypeScript는 오류 처리, 비동기 실행, 공유 상태, 라이브러리 동작이 다릅니다. AI Agent가 만든 코드는 임시 연결 코드와 의존성 교체까지 함께 만들 수 있으므로, 기존 구현의 결과를 저장하고 프로토콜, 상태 변화, 실패 복구를 별도로 비교해야 합니다.

대형 프로젝트는 점진 이전과 일괄 재작성 중 무엇이 안전한가요?

활발히 변경되는 대형 저장소라면 보통 컴포넌트 단위의 점진 이전이 안전합니다. 작은 변경을 주 저장소에 계속 합치면 회귀 원인을 좁히고 이전 버전으로 되돌리기 쉽습니다. 다만 상태가 깊게 얽힌 조정 계층은 병렬 구현 자체가 더 큰 복잡성을 만들 수 있으므로, 먼저 순수 로직과 의존성이 적은 모듈에서 시작해야 합니다.

AI가 생성한 Rust 코드는 어떤 회귀 테스트를 거쳐야 하나요?

단위 테스트만으로는 부족합니다. 기존 TypeScript 구현을 기준선으로 두고, 동일한 입력에 대한 결과와 오류, 이벤트 순서, 파일 상태, 프로토콜 응답을 비교해야 합니다. 대표 업무 시나리오를 포함한 종단 간 테스트와 플랫폼별 빌드 테스트도 필요합니다. 코드 검토 기록에는 생성 코드, 자동 수정, 사람이 승인한 변경을 구분해 남기는 편이 좋습니다.

크로스 플랫폼 런타임 이전에 별도 맥 테스트 환경이 필요한가요?

macOS 전용 의존성이나 Apple 도구 체인, 서명, 네이티브 확장이 포함되면 별도 맥 환경이 필요합니다. Linux에서 통과한 Rust 빌드가 macOS의 링커, 권한, 네이티브 라이브러리, 패키징 단계까지 통과한다는 보장은 없습니다. 공통 로직은 Linux 병렬 풀에서 처리하고, 맥 관련 단계는 독립된 검증 환경에서 최종 확인해야 합니다.

zekmac M4 원격 노드

팀의 런타임 이전을 안전하게 검증할 맥 환경을 준비하세요

zekmac의 맥 대여 서비스로 새로운 런타임을 별도 환경에서 부담 없이 시험할 수 있습니다.