왜 증분보다 전체 빌드가 머신 한계를 더 잘 보여 주는가
일상 개발에서 Xcode 증분 빌드는 하드웨어 격차를 많이 가린다. 파일 하나를 고치면 영향받는 target만 다시 컴파일되므로
8 GB MacBook Air와 16 GB Pro 모두 「쓸 만하다」고 느껴진다.
그러나 main 브랜치 머지 후 CI가 Clean Build를 돌리거나, 로컬에서
xcodebuild clean build로 Release 설정을 검증할 때는
컴파일러가 모든 Swift 모듈을 동시에 올리고 전체 타입 검사·Extension 링크까지 수행한다.
이때가 메모리, 방열, CPU 지속 부하를 가장 정확히 시험하는 순간이다.
독립 개발자에게 자주 들리는 불만이 있다. 「노트북이 절반쯤 컴파일되면 팬이 미친 듯이 돌고, Simulator가 멈추고, Slack 전환도 버벅인다.」 원인은 Xcode 버전보다 전체 빌드가 머신을 장시간 고부하로 밀어 올리는 것에 가깝다. 노트북의 방열과 통합 메모리 용량은 이동 환경을 전제로 설계되었지, 5~10분 연속 컴파일을 전제로 하지 않았다. 이 글은 「동일 프로젝트·동일 명령·다른 머신」의 벽시계 차이에 집중해, 로컬 하드웨어를 업그레이드할지, 무거운 컴파일을 클라우드 전용 노드로 옮길지 판단하는 데 도움을 준다.
샘플: SwiftUI 중형 App(약 11.8만 줄 Swift/ObjC, Widget·Share Extension·Notification Service Extension 등 Extension target 3개), CocoaPods + 로컬 Swift Package 의존 14개.
툴체인: macOS 15 Sequoia, Xcode 16.4, -jobs 10 병렬 컴파일(M4 물리 코어 수에 맞춤).
대조기 A: MacBook Air M2 · 8 GB · 256 GB · 팬 없음(2022).
대조기 B: MacBook Pro 14" M1 Pro · 16 GB · 512 GB(2021, 전원 연결).
클라우드: PixVPS Mac mini M4 · 10코어 · 16 GB · 256 GB NVMe · 1 Gbps 전용 대역폭(일본 도쿄 노드).
각 항목 3회 반복 후 중앙값 사용. 매 회전 전 rm -rf ~/Library/Developer/Xcode/DerivedData/*로 콜드 스타트 보장.
통일된 테스트 방법: 「각자 제멋대로 빌드」 방지
컴파일 속도 비교에서 가장 흔한 실수는 세 머신의 상태를 다르게 두는 것이다. 한 대는 Chrome 탭 40개, 다른 한 대는 방금 재부팅, 또 다른 한 대는 지난주 DerivedData가 남아 있다. 아래 기준선을 고정해 숫자를 가로로 비교 가능하게 했다.
-
01
동일 Git commit
세 머신 모두
git checkout v2.4.0-buildbench로 의존 버전과Package.resolved를 고정해 SPM 해석 시간 간섭을 제거했다. -
02
CLI 빌드, GUI 비활성
Xcode UI의 Product → Build 대신
xcodebuild만 사용하고/usr/bin/time -l로 벽시계·피크 메모리를 수집했다. -
03
「실제 데스크톱」 백그라운드 부하
로컬 MacBook에는 Slack, Chrome(탭 8개)을 추가 실행(Simulator 미기동). 클라우드 M4는 SSH 세션과 빌드 스크립트만 돌려 무인 CI 환경을 시뮬레이션했다.
-
04
두 종류 빌드 각각 측정
Debug
clean build(개발 검증)와 Releasearchive(출시 경로)를 나눠 소요 시간과 swap 페이지 수를 기록했다.
Debug 빌드 예시:
xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug clean build -destination 'generic/platform=iOS' -jobs 10.
타이머는 명령 실행부터 ** BUILD SUCCEEDED ** 출력까지이며, pod install·인증서 가져오기는 포함하지 않는다.
Clean Build 벽시계: M4와 두 세대 MacBook
Debug 전체 빌드 중앙값은 아래와 같다. M4 클라우드 노드는 M1 Pro 로컬보다 약 15% 빠르고, M2 Air보다는 2배 가까이 빠르다. 격차의 핵심은 M2 Air가 3분째부터 메모리 압축·swap을 유발하고, 과열로 CPU 클럭이 3.4 GHz에서 약 2.6 GHz로 떨어지는 구간이다.
| 머신 | Debug Clean Build | Release Archive | 피크 메모리 | swap 발생 |
|---|---|---|---|---|
| Mac mini M4(PixVPS 전용) | 3m 41s | 3m 52s | 12.4 GB | 없음 |
| MacBook Pro M1 Pro 16 GB | 4m 18s | 4m 56s | 14.8 GB | 경미(< 200 MB) |
| MacBook Air M2 8 GB | 7m 09s | 8m 47s | 7.9 GB + 3.2 GB swap | 있음 |
Release Archive 격차는 Debug보다 더 크다. 최적화 단계가 높고 링크가 메모리를 더 잡아먹기 때문이다. M2 Air는 Archive 중 swap 피크 4.1 GB, 벽시계 거의 9분. 동일 프로젝트를 M4에서 돌리면 16 GB 물리 메모리를 넘지 않아 컴파일 곡선이 평탄하고 「후반에 갑자기 느려지는」 꺾임이 없다. 출시 플로우에서 주 1회 이상 전체 Archive를 돌린다면, 이 차이는 곧 대기 시간과 노트북 가용성 비용으로 이어진다.
증분 빌드: 체감과 전체 빌드 결론이 다른 이유
개발 경험을 완성하기 위해 「Swift 파일 하나 수정 후 증분 빌드」도 측정했다. IDE에서 Cmd+B를 누를 때 가장 흔한 경로다. 세 머신 격차는 크게 줄어든다: M4 클라우드 17초, M1 Pro 22초, M2 Air 38초(Chrome 백그라운드 유지). 증분은 영향 모듈만 다시 컴파일하므로 메모리 피크가 5 GB를 넘지 않아 M2 Air도 swap이 발생하지 않는다.
즉 시간의 90%를 작은 단위 반복 개발에 쓴다면 로컬 8 GB Air로도 충분한 경우가 많다. 고통은 출시 주간, 대규모 의존성 업그레이드, 브랜치 전환 후 첫 전체 빌드에 집중된다. 많은 팀이 「일상 코딩은 로컬, 전체 빌드는 CI」로 나눈다. 그러나 GitHub 호스팅 Runner는 피크에 20분 이상 대기가 붙어 체감이 로컬 Air보다 나을 때가 없다. 전용 클라우드 M4 한 대에 전체 빌드를 고정하는 것은 「로컬에서 버티기」와 「공용 큐」 사이의 세 번째 선택지다.
DerivedData를 유지한 뒤 두 번째 Debug 전체 빌드는 M4 2m 14s, M1 Pro 2m 48s까지 단축된다. 클라우드 노드는 캐시를 장기 보관하기에 적합하다. 반면 로컬 Air 디스크가 20 GB 남짓이면 캐시를 자주 비워 「콜드 전체 빌드」를 더 자주 맞는다. 용량이 필요하면 SSD +1TB 확장($2.9/일부터)으로 여러 Xcode 버전과 캐시를 클라우드에 둘 수 있다.
발열, 팬, 「컴파일 중에 다른 일을 할 수 있는가」
컴파일은 스톱워치만의 문제가 아니다. 병렬 업무 흐름에도 영향을 준다. 전체 빌드 진행 중 본체 온도·팬 RPM을 기록했다(M4 mini는 외부 온도 센서, 노트북은 내장 센서).
| 머신 | 빌드 3분째 키보드/본체 온도 | 팬 RPM / 소음 | 동시 Simulator 디버깅 |
|---|---|---|---|
| Mac mini M4(클라우드) | 외함 약 38°C | 팬 거의 정지, < 25 dB | 별도 Simulator 가능(SSH 원격 관찰) |
| MacBook Pro M1 Pro | 키보드면 약 44°C | 약 3200 RPM, 들리지만 거슬리지 않음 | 가능하나 UI 끊김 뚜렷 |
| MacBook Air M2 8 GB | 키보드면 약 47°C | 팬 없음, 본체 뜨거움, 클럭 다운 | 비권장, Simulator 자주 크래시 |
M2 Air의 무팬 설계는 지속 컴파일에서 칩 보호를 위해 적극적으로 클럭을 낮춘다. 처음 2분은 M1 Pro와 비슷한데 후반 3분이 늘어져 총 7분이 된다. 클라우드 Mac mini는 데스크톱 방열 형태라 M4 10코어가 오랫동안 고클럭을 유지할 수 있다. 실무에서는 SSH 세션에서 전체 빌드를 백그라운드로 돌리고, 로컬 Windows·Linux 주력기에서 코딩·회의·문서 작업을 이어가면 된다.
16 GB 통합 메모리: 충분과 부족의 경계
이번 프로젝트 Debug 전체 빌드 피크는 약 12.4 GB로 16 GB 머신의 편안한 구간에 있다. 코드가 20만 줄을 넘거나 Xcode + Simulator + Instruments를 동시에 켜면 16 GB 로컬도 한계에 닿는다. 동일 M1 Pro에서 iOS 17 Simulator로 UI 테스트를 겹쳤을 때 피크 15.6 GB, swap 800 MB, 전체 빌드가 4m 18s에서 5m 44s로 늘어났다.
M2 Air 8 GB는 컴파일 시작 90초 만에 메모리 상한에 닿아 압축·페이지 아웃이 시작된다.
memory_pressure 로그에 vm_compressor 이벤트가 쏟아지고
컴파일 스레드가 메모리 해제를 기다리며 벽시계가 거의 2배로 늘어난다.
이것은 Xcode 「최적화 부족」이 아니라 물리 메모리 한계다.
클라우드 M4 16 GB는 중형 iOS 프로젝트 다수에 swap 없이 버티는 최소 사양에 가깝지,
과잉 스펙이 아니다.
일부 클라우드는 가상화 macOS나 초과 판매 호스트를 제공해, 컴파일 시 이웃 테넌트와 CPU를 나눠 쓰면 전체 빌드 시간이 부하에 따라 30% 이상 흔들린다. PixVPS는 가상화·초과 판매 없이 Mac mini M4 물리 머신을 전용 제공한다. 이번 3회 반복 표준편차는 4초 이내로 안정적인 기준선으로 삼을 수 있다.
실측 재현: 스크립트와 타이밍 주의점
아래 최소 스크립트를 로컬과 클라우드 노드에서 각각 실행해 CSV로 비교할 수 있다.
프로젝트 루트에 scripts/bench_clean_build.sh로 저장한다.
#!/bin/bash
set -euo pipefail
SCHEME="MyApp"
WORKSPACE="MyApp.xcworkspace"
rm -rf ~/Library/Developer/Xcode/DerivedData/*
/usr/bin/time -l xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -configuration Debug clean build -destination 'generic/platform=iOS' -jobs "$(sysctl -n hw.ncpu)" 2>&1 | tee /tmp/xcode_bench.log
grep -E 'real|maximum resident set size' /tmp/xcode_bench.log
주의: 새 머신에서는 먼저 xcodebuild -runFirstLaunch를 실행한다.
xcode-select -p가 의도한 Xcode를 가리키는지 확인한다.
타이밍 중 Xcode GUI를 수동으로 열지 말 것(SourceKit·인덱싱이 자원을 잡아먹는다).
클라우드 비교는 SSH에서 스크립트를 실행하고 caffeinate -dims로 절전을 막는다(로컬 노트북 테스트에도 동일).
VNC는 진행 관찰용으로만 쓰고, VNC 안에서 Xcode GUI를 켠 채 CLI 빌드를 재지 말 것——그래픽 세션이 추가로 1~2 GB를 쓴다.
전체 빌드를 클라우드 M4로 옮길 때
로컬 MacBook을 M4 Pro 32 GB로 올리려면 수천 달러가 든다. 연간 출시 피크는 수십 일에 그칠 수 있다. 「주 1~2회 Archive 때문에 노트북이 무릎 위에서 뜨겁다」가 고통이고 「저장할 때마다 30초」가 아니라면, 일 단위 전용 M4 임대가 경제적일 때가 많다: $21.1/일, $57.1/주, $105.7/월, 계약 없음, 결제 후 1–5분 개통, SSH·브라우저 VNC 이중 접속.
PixVPS 다섯 노드——싱가포르, 일본(도쿄), 한국(서울), 홍콩, 미국 동부——는 하드웨어 동일 가격이다.
국내 팀은 서울 노드 SSH로 전체 빌드를 돌리면 벽시계는 로컬과 거의 같고 발열·소음만 데이터센터에 남긴다.
GitHub Actions 셀프 호스팅 Runner나 Fastlane과 조합해 로컬 push 후 클라우드 xcodebuild archive를 트리거하고,
완료된 .ipa를 받거나 TestFlight에 직접 올릴 수 있다(흐름은 클라우드 Mac Xcode CI/CD 실전 가이드 참고).
또 다른 패턴: 주력 PC가 Windows이고 iOS 외주를 가끔 맡는 경우 MacBook을 살 필요 없이 출시 주에 클라우드 M4를 이틀 빌려 Xcode·인증서를 올리고 끝내면 된다. 16 GB 통합 메모리, 1 Gbps 전용 대역폭, 99.9% SLA, 7×24 실제 지원, 티켓 1시간 내 응답. 대형 캐시가 필요하면 SSD +1TB($2.9/일) 추가. 야간 다중 App 매트릭스 빌드는 Thunderbolt 5 병렬($1.9/일부터, 80 Gbps 다중 연결)도 검토할 만하다—— 자세한 수치는 TB5 병렬 클러스터 실측을 보라.
| 상황 | 권장 | 클라우드 M4 역할 |
|---|---|---|
| M2 Air 8 GB, 월 전체 빌드 < 4회 | 출시일에 일 단위 임대 | 임시 컴파일 스테이션, swap 회피 |
| M1/M2 Pro 16 GB, 일상 OK·출시 주만 느림 | 출시 주 Archive만 클라우드 | 로컬 코딩, 클라우드 무거운 빌드 |
| Mac 없음, iOS 외주 | 주 단위 임대 + VNC 디버깅 | 완전한 Xcode 환경, 끝나면 해제 |
| 하루 여러 번 전체 CI | 상시 클라우드 M4 Runner | 월 $105.7, 대기 없음 |
전체 빌드가 재는 것은 「벤치 점수가 높은 칩」이 아니라 5분 안에 안정적으로 끝내고 병렬 업무를 희생하지 않는 능력이다. 로컬 MacBook은 여전히 최고의 일상 코딩 터미널이고, 클라우드 M4 전용 노드는 「컴파일 피크」를 노트북에서 떼어 내는 전용 연산이다. 연간 수십 일만 쓰는 피크를 위해 통째로 새 머신을 살 필요가 없다.
Xcode 전체 빌드를 팬 소음 없는 M4 노드로
PixVPS Mac mini M4 전용 물리 머신: 10코어 CPU, 16 GB 통합 메모리, Debug 전체 빌드 약 3분 40초, 전 과정 swap 없음. SSH / VNC 접속, 일 $21.1부터.