# Mac이 열로 인해 성능 저하(thermal throttling) 상태인지 알려주는 macOS 앱 개발기

> Clean Markdown view of GeekNews topic #25416. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=25416](https://news.hada.io/topic?id=25416)
- GeekNews Markdown: [https://news.hada.io/topic/25416.md](https://news.hada.io/topic/25416.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-12-29T23:33:24+09:00
- Updated: 2025-12-29T23:33:24+09:00
- Original source: [stanislas.blog](https://stanislas.blog/2025/12/macos-thermal-throttling-app/)
- Points: 5
- Comments: 1

## Summary

Mac의 **열 스로틀링 상태를 실시간으로 감지**하는 오픈소스 앱 **MacThrottle**은 SwiftUI로 구현된 메뉴 막대 도구입니다. `thermald`가 게시하는 Darwin **`notifyd` 알림**을 직접 구독해 루트 권한 없이 열 압력 수준을 읽어들이며, 온도·팬 속도 그래프와 상태별 색상 아이콘으로 직관적인 피드백을 제공합니다. Apple Silicon Mac의 열 관리 한계를 진단하려는 개발자와 파워유저에게 간결한 모니터링 수단을 제시합니다.

## Topic Body

- **MacThrottle**은 Mac이 과열로 인해 성능을 제한할 때 이를 메뉴 막대에서 시각적으로 알려주는 **SwiftUI 기반 앱** - [오픈소스](https://github.com/angristan/MacThrottle)  
- macOS의 **`ProcessInfo.thermalState`** API와 **`powermetrics`** 명령어를 비교하며, 시스템의 실제 열 상태를 정확히 감지하기 위한 방법을 탐색  
- 최종적으로 **`thermald`가 Darwin의 `notifyd` 시스템에 게시하는 알림**을 활용해 루트 권한 없이 열 상태를 읽는 방식 구현  
- 앱은 **온도·팬 속도 그래프**, **상태별 색상 아이콘**, **macOS 알림 기능**을 포함하며, 로그인 시 자동 실행도 지원  
- Apple Silicon Mac의 **열 관리 상태를 실시간으로 파악**할 수 있는 도구로, 개발자와 파워유저에게 유용한 진단 수단 제공  
  
---  
  
### Mac의 열 스로틀링 문제 인식  
- M2 MacBook Air에서 외부 4K 120Hz 디스플레이 사용 시 **성능 저하와 반응 지연**이 발생  
  - 팬이 없어 소음을 감지할 수 없지만, CPU 사용률이 100%인 상태에서 전력 사용량이 감소함  
- iStat Menus와 MX Power Gadget을 통해 **CPU 주파수와 전력 하락**을 확인하며 열 스로틀링을 진단  
- M4 Max MacBook Pro에서도 동일 현상 발생, 14인치 모델의 **열 설계 한계**로 인한 문제로 언급  
- Apple Silicon의 전력 효율은 여전히 높지만, **열 상태를 직접 감지할 방법**을 찾고자 함  
  
### macOS에서 열 상태를 프로그래밍적으로 확인하기  
- macOS는 여러 방식으로 열 상태를 노출하지만 **일관성이 부족**  
- Apple이 권장하는 방법은 `Foundation`의 **`ProcessInfo.thermalState`** 사용  
  - 출력 예시: `nominal`, `fair`, `serious`, `critical`  
- 루트 권한이 필요한 **`powermetrics -s thermal`** 명령어도 동일한 정보를 제공하지만,  
  두 방식의 **상태 구분 단위가 다름**  
  - 예: `fair`는 `powermetrics`의 `moderate`와 `heavy` 두 상태를 모두 포함  
- 실제 스로틀링 시점은 `powermetrics`에서 `heavy`로 표시되지만, `ProcessInfo`에서는 구분 불가  
  
### `thermald`와 Darwin 알림 시스템 활용  
- `powermetrics`의 데이터는 **`thermald` 데몬**에서 가져오며,  
  `thermald`는 현재 열 압력 상태를 **`notifyd` 시스템 이벤트**로 게시  
- `notifyutil -g com.apple.system.thermalpressurelevel` 명령으로 상태 확인 가능  
- `OSThermalNotification.h` 헤더에서 정의된 열 압력 수준:  
  - `nominal`, `moderate`, `heavy`, `trapping`, `sleeping`  
- Swift 코드로 `notify_register_check`와 `notify_get_state`를 호출해  
  **루트 권한 없이 실시간 열 상태를 읽는 기능** 구현  
  
### MacThrottle 앱 개발  
- **SwiftUI와 MenuBarExtra**를 사용해 메뉴 막대 전용 앱 제작  
  - 온도계 아이콘 색상으로 상태 표시 (녹색→적색)  
  - `Info.plist`의 `LSUIElement`를 `true`로 설정해 Dock 아이콘 비활성화  
  
#### 초기 접근: `powermetrics` 루트 헬퍼  
- 초기에 루트 권한이 필요한 `powermetrics`를 사용하기 위해  
  **LaunchDaemon과 bash 스크립트**로 헬퍼 프로세스 구성  
  - `/usr/local/bin/mac-throttle-thermal-monitor`가 10초마다 상태를 `/tmp` 파일에 기록  
  - 앱은 해당 파일을 주기적으로 읽어 표시  
  
#### 개선: `thermald` IPC 알림 사용  
- `notifyd` 이벤트를 직접 구독하는 방식으로 전환  
  - 루트 권한 불필요, 코드 단순화  
  
### 온도 및 팬 속도 표시  
- CPU/GPU 온도와 팬 속도를 그래프로 표시  
- 초기에는 **IOKit 비공개 API** 사용 시 온도가 실제보다 낮게 표시됨 (~80°C)  
- 오픈소스 **Stats** 프로젝트를 참고해 **SMC 인터페이스**로 전환  
  - SoC 세대별로 다른 키(`Tp0D`, `Tf0E` 등)를 사용해야 함  
- SMC가 작동하지 않을 경우 IOKit으로 폴백  
  
### 메뉴 막대 그래프 구현  
- 그래프는 3가지 정보를 동시에 표시  
  - 배경 색상: 열 상태 (녹색~적색)  
  - 실선: CPU 온도  
  - 점선: 팬 속도 비율  
- 2초 간격으로 데이터 수집, **10분 단위 히스토리** 유지  
- `onContinuousHover`로 툴팁 제공,  
  `.drawingGroup`을 추가해 **GPU 렌더링으로 120Hz 디스플레이에서도 부드럽게 표시**  
  
### macOS 알림 및 자동 실행  
- 열 상태 변화 시 **알림 전송 기능** 추가  
  - 특정 상태 전환이나 복구 시 알림 가능  
- **`SMAppService` API**로 로그인 시 자동 실행 설정 지원  
  - `register()` / `unregister()` / `status` 메서드로 제어  
  
### 배포 및 사용  
- Apple Developer 계정이 없어 **공식 공증(notarization)** 불가  
  - GitHub 릴리스에서 설치 시 `Privacy and Security`에서 수동 승인 필요  
  - 일부 Mac에서는 **Xcode로 직접 빌드**해야 실행 가능  
- 설치 및 빌드 방법은 GitHub README에 명시  
  
### 결론  
- MacThrottle은 **Apple Silicon Mac의 열 스로틀링 상태를 실시간 감시**할 수 있는 경량 도구  
- 루트 권한 없이 동작하며, **시각적 피드백·알림·그래프 기능**을 통해  
  개발자와 고성능 작업 사용자에게 **시스템 열 상태 인식**을 제공

## Comments



### Comment 48414

- Author: neo
- Created: 2025-12-29T23:33:24+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=46410402) 
- 2019년형 **MacBook Pro i9**을 썼는데, 열 스로틀링 감지 함수는 이렇게 간단히 쓸 수 있을 것 같음  
  ```js
  function isThermalThrottling() {
    return true;
  }
  ```  
  농담이지만, 고가의 i9 CPU를 샀는데 i7보다 성능이 떨어지는 게 꽤 실망스러웠음
  - 나도 같은 모델을 쓰는데, 오른쪽 포트로 충전해야만 문제를 해결할 수 있었음  
    이유는 모르겠지만 그렇게 하니 스로틀링이 사라졌음  
    그래도 **macOS**와 **Logic** 기반 워크플로우가 익숙해서 계속 쓰고 있음  
    리눅스로 옮길 수도 있겠지만, 지금은 꽤 쓸 만한 머신임
  - 나도 2019 i9 모델을 썼는데, **VRM 모듈에 써멀 패드**를 붙이니 완전히 새 컴퓨터처럼 변했음  
    두 개의 외부 모니터와 Adobe Creative Suite를 쓸 때마다 스로틀링이 심했는데, 이 패드로 해결됨  
    단점은 하판이 뜨거워져 무릎 위에 두기 어렵다는 점이지만, 전혀 후회하지 않음  
    지금은 **M3 MacBook Air(24GB RAM)** 로 바꿨고 매우 만족 중임  
    아직 2019 모델을 쓰는 사람이라면 꼭 VRM 써멀 패드 개조를 고려해보길 추천함
  - 사실 i9 자체가 **노트북용으로 부적합한 CPU**였다고 생각함  
    Dell에서도 i9을 i7으로 바꾸자마자 훨씬 나아졌음  
    “큰 숫자 = 더 좋은 CPU”라는 마케팅에 속은 셈임
  - 나도 같은 문제를 겪었음, 특히 **외부 모니터 두 대**를 연결했을 때 심했음  
    이후 **M1 Max**로 바꾸자 완전히 다른 세상이었음  
    지금은 M3 Max로 업그레이드했고, Apple Silicon은 오래 버틸 것 같음
  - 그 노트북은 내가 써본 **최악의 컴퓨터**였음  
    부팅하자마자 팬이 돌고, Thunderbolt 장치 연결 시 커널 패닉도 자주 발생했음  
    지금 쓰는 **M1 Max MBP**는 완벽하게 안정적임

- 프로젝트가 꽤 괜찮아 보임  
  다만 macOS에서 개발이 점점 어려워지고 있는데, 스로틀링을 감지해도 실제로 **무엇을 할 수 있을지**는 의문임  
  팬 속도 조정도 안 되고, 언더볼팅도 불가능하지 않나?
  - 나 같은 경우 **iStat Menus**로 팬 커브를 직접 조정했음  
    기본 커브가 너무 느려서 스로틀링이 먼저 발생했거든  
    Apple Silicon에서는 [**High Power Mode**](https://support.apple.com/en-us/101613)를 쓰면 팬이 더 빠르게 돌아감  
    지금은 커스텀 커브를 안 쓰지만, 14" M4 Max에서는 꽤 시끄러움  
    **MacBook Air**는 팬이 없으니 그냥 열을 식히는 수밖에 없음
  - 나는 **Macs Fan Control**을 써서 CPU 온도에 따라 팬 RPM을 조절함  
    기본 설정으로는 90도 이상 올라가서, 더 보수적으로 세팅했음  
    [GitHub 링크](https://github.com/crystalidea/macs-fan-control)
  - 이런 앱이 꼭 필요했는데 이제 생겼음  
    가끔 프로세스가 폭주해서 스로틀링이 생기는데, 그걸 알아차리기 전까지 배터리가 반쯤 닳아 있음
  - 결국 할 수 있는 건 **앱을 종료하거나 잠시 쉬는 것**뿐임  
    백그라운드에서 돌아가는 앱이 많을 때 이런 문제가 자주 생김

- Homebrew에 넣으면 **무료로 코드 서명과 공증**을 받을 수 있음  
  그렇게 배포되면 정말 좋겠음
  - 좋은 정보임. 혹시 **Windows용 무료 서명 방법**도 있는지 궁금함
  - 오, 몰랐음. 개발자 설정에 따라 달라지는 줄 알았는데 찾아봐야겠음

- 내 가설은 CPU 문제가 아니라 **USB 컨트롤러가 열을 포화시키는 것**임  
  CPU/GPU가 아니라 본체가 과열돼서 열 방출이 막히고 결국 스로틀링이 생기는 구조 같음  
  다른 어댑터나 모니터로 실험해볼 필요가 있음
  - 나도 2019 i9을 쓰는데, **충전 포트를 바꾸자** 스로틀링이 사라졌음  
    네 말이 맞는 것 같음
  - 완전히 이해한 건 아니지만, 내 **M2 Air**도 비슷한 증상이 있음  
    4K 144Hz 모니터에 연결해 Zoom이나 영상 스트림을 여러 개 켜면 발열이 심해짐  
    USB 컨트롤러 때문이라기보단 단순히 부하가 커서 그런 듯함
  - 이런 현상을 **thermal soaking**이라고 부름

- 사이트가 트래픽 폭주로 죽은 듯함  
  저장소는 [angristan/MacThrottle](https://github.com/angristan/MacThrottle)
  - 수정 완료했음. Cloudflare Workers가 **fail closed** 모드로 설정돼 있어서 트래픽을 막고 있었음

- iStat Menus에서 CPU 100%인데 전력 사용량이 낮으면 스로틀링이라 생각할 수 있지만,  
  **저전력 USB-C 충전기**에 연결된 경우에도 같은 현상이 생김  
  충전기 전력을 감지하는 기능을 추가하면 좋을 듯함
  - 나도 **M1 MacBook Air**로 D&D 세션을 하다가 같은 문제를 겪었음  
    충전 중이라 더워져서 스로틀링이 심했는데, 세션 전에 미리 충전하니 해결됨
  - 예전에 **전원 어댑터 출력이 부족**해서 게임을 하다 배터리가 닳아 꺼진 적이 있었음  
    이후 세대에서 더 큰 전원 어댑터가 나온 이유를 이해했음
  - 그렇다면 왜 **코어 온도만으로는 스로틀링을 판단할 수 없는지** 궁금함  
    온도가 바로 제어 변수 아닌가?
  - iStat Menus에서 충전기 전력을 보여주긴 하지만, 왜 이런 현상이 생기는지는 여전히 의문임

- CPU 사용률과 시스템 전력량을 **메뉴바에 표시**해두면 이상 징후를 바로 알 수 있음  
  [exelban/stats](https://github.com/exelban/stats)
  - 나도 그렇게 해서 스로틀링을 처음 의심했음  
    CPU 사용률은 높은데 전력량이 줄어드는 걸 보고 눈치챘음

- 다음 **MacBook Air M5**에는 **Vapor Chamber 냉각**이 들어갔으면 좋겠음  
  지금은 Apple이 소음 최소화를 열 방출보다 우선시하는 것 같음  
  그래서 팬 최소 속도를 강제로 높여둠
  - Vapor Chamber는 **순간적인 열 분산**에는 좋지만, 결국 열은 **알루미늄 바디**로 전달됨  
    바디가 환경과 열평형에 도달하면 방출량이 한계에 부딪힘  
    팬이 있다면 구리판과 바람으로 충분히 해결 가능함  
    결국 **에너지 보존**의 문제임

- **thermal pressure 알림 버그**가 있는 것 같음  
  혹시 앱에서 그런 문제를 겪었는지 궁금함  
  [관련 이슈](https://github.com/macmade/Hot/issues/73)
  - 나도 `ProcessInfo.processInfo.thermalState`를 쓸 때 상태가 갱신되지 않는 걸 봤음  
    하지만 지금 쓰는 **thermald 알림 방식**에서는 그런 문제가 없음

- 왜 `@_silgen_name`으로 **Darwin API를 직접 선언**했는지 궁금함  
  `import Darwin`으로는 접근이 안 되나?
  - 실제로 `import Darwin`만으로는 해당 API가 노출되지 않는 것 같음
