5 puntos por GN⁺ 2025-12-29 | 1 comentarios | Compartir por WhatsApp
  • MacThrottle es una app basada en SwiftUI que muestra visualmente en la barra de menús cuando la Mac limita su rendimiento por sobrecalentamiento - código abierto
  • Compara la API ProcessInfo.thermalState de macOS y el comando powermetrics para explorar cómo detectar con precisión el estado térmico real del sistema
  • Finalmente implementa una forma de leer el estado térmico usando las notificaciones que thermald publica en el sistema notifyd de Darwin, sin requerir privilegios de root
  • La app incluye gráficas de temperatura y velocidad del ventilador, íconos por color según el estado y notificaciones de macOS, además de soporte para iniciarse automáticamente al iniciar sesión
  • Es una herramienta para entender en tiempo real el estado de gestión térmica de las Mac con Apple Silicon, útil como recurso de diagnóstico para desarrolladores y usuarios avanzados

Reconocer el problema del thermal throttling en la Mac

  • En una M2 MacBook Air, al usar una pantalla externa 4K 120Hz, se producían caídas de rendimiento y retrasos de respuesta
    • Como no tiene ventilador, no se puede detectar ruido, pero con el CPU al 100% el consumo de energía disminuía
  • Con iStat Menus y MX Power Gadget se confirmó la caída de frecuencia y de consumo del CPU, diagnosticando thermal throttling
  • El mismo fenómeno apareció también en una M4 Max MacBook Pro, mencionado como un problema derivado de las limitaciones del diseño térmico del modelo de 14 pulgadas
  • Aunque la eficiencia energética de Apple Silicon sigue siendo alta, se buscó una forma de detectar directamente el estado térmico

Cómo comprobar programáticamente el estado térmico en macOS

  • macOS expone el estado térmico de varias formas, pero carecen de consistencia
  • El método recomendado por Apple es usar ProcessInfo.thermalState de Foundation
    • Ejemplos de salida: nominal, fair, serious, critical
  • El comando powermetrics -s thermal, que requiere privilegios de root, también entrega esa información,
    pero ambos métodos usan niveles de clasificación distintos
    • Por ejemplo, fair incluye tanto moderate como heavy de powermetrics
  • En el momento en que ocurre el throttling real, powermetrics lo muestra como heavy, pero ProcessInfo no permite distinguirlo

Uso de thermald y del sistema de notificaciones de Darwin

  • Los datos de powermetrics provienen del daemon thermald,
    y thermald publica el estado actual de presión térmica como eventos del sistema notifyd
  • Es posible consultar el estado con el comando notifyutil -g com.apple.system.thermalpressurelevel
  • Niveles de presión térmica definidos en el encabezado OSThermalNotification.h:
    • nominal, moderate, heavy, trapping, sleeping
  • Con código Swift que llama a notify_register_check y notify_get_state,
    se implementó una función para leer en tiempo real el estado térmico sin privilegios de root

Desarrollo de la app MacThrottle

  • Se creó una app exclusiva para la barra de menús usando SwiftUI y MenuBarExtra
    • El estado se muestra con el color de un ícono de termómetro (verde→rojo)
    • Se desactiva el ícono del Dock configurando LSUIElement de Info.plist en true

Enfoque inicial: helper de root con powermetrics

  • Al inicio, para usar powermetrics, que requiere privilegios de root,
    se construyó un proceso auxiliar con LaunchDaemon y un script en bash
    • /usr/local/bin/mac-throttle-thermal-monitor escribía el estado cada 10 segundos en un archivo de /tmp
    • La app leía periódicamente ese archivo para mostrarlo

Mejora: uso de notificaciones IPC de thermald

  • Luego se cambió a un método que suscribe directamente los eventos de notifyd
    • Ya no requiere privilegios de root y simplifica el código

Visualización de temperatura y velocidad del ventilador

  • Muestra en gráficas la temperatura del CPU/GPU y la velocidad del ventilador
  • Al principio, usando API privadas de IOKit, la temperatura aparecía más baja de lo real (~80°C)
  • Tomando como referencia el proyecto de código abierto Stats, se cambió a la interfaz SMC
    • Hay que usar claves distintas según la generación del SoC (Tp0D, Tf0E, etc.)
  • Si SMC no funciona, hace fallback a IOKit

Implementación de la gráfica en la barra de menús

  • La gráfica muestra tres tipos de información al mismo tiempo
    • Color de fondo: estado térmico (verde~rojo)
    • Línea continua: temperatura del CPU
    • Línea punteada: proporción de velocidad del ventilador
  • Recolecta datos cada 2 segundos y mantiene un historial de 10 minutos
  • Ofrece tooltip con onContinuousHover,
    y al añadir .drawingGroup se logra renderizado por GPU para mostrarlo con fluidez incluso en pantallas de 120Hz

Notificaciones de macOS e inicio automático

  • Se añadió una función para enviar notificaciones cuando cambia el estado térmico
    • Puede notificar en transiciones a estados específicos o cuando se recupera
  • También soporta configuración de inicio automático al iniciar sesión con la API SMAppService
    • Se controla con los métodos register() / unregister() / status

Distribución y uso

  • Como no hay cuenta de Apple Developer, no fue posible la notarización oficial
    • Al instalar desde GitHub Releases, se requiere aprobación manual en Privacy and Security
    • En algunas Mac, solo puede ejecutarse si se compila directamente con Xcode
  • El método de instalación y compilación está explicado en el README de GitHub

Conclusión

  • MacThrottle es una herramienta ligera para vigilar en tiempo real el estado de thermal throttling en Mac con Apple Silicon
  • Funciona sin privilegios de root y, mediante retroalimentación visual, notificaciones y gráficas,
    ofrece a desarrolladores y usuarios de cargas intensivas visibilidad sobre el estado térmico del sistema

1 comentarios

 
GN⁺ 2025-12-29
Comentarios de Hacker News
  • Usé una MacBook Pro i9 de 2019, y la función para detectar thermal throttling podría ser así de simple

    function isThermalThrottling() {
      return true;
    }
    

    Es broma, pero sí fue bastante decepcionante comprar un CPU i9 caro y que rindiera peor que un i7

    • Yo también uso ese mismo modelo, y solo pude resolverlo cargando por el puerto derecho
      No sé por qué, pero así desapareció el throttling
      Aun así, sigo usándola porque ya estoy acostumbrado al flujo de trabajo con macOS y Logic
      Podría cambiarme a Linux, pero por ahora sigue siendo una máquina bastante usable
    • Yo también usé el modelo i9 de 2019, y al ponerle thermal pads al módulo VRM se convirtió por completo en otra computadora
      El throttling era terrible cada vez que usaba dos monitores externos y Adobe Creative Suite, pero con esos pads se solucionó
      La desventaja es que la tapa inferior se calienta y cuesta usarla sobre las piernas, pero no me arrepiento en absoluto
      Ahora me cambié a una MacBook Air M3 (24GB RAM) y estoy muy satisfecho
      Si alguien todavía usa el modelo 2019, de verdad le recomiendo considerar la modificación con thermal pads en el VRM
    • La verdad, creo que el i9 en sí era un CPU inadecuado para laptops
      Incluso en Dell todo mejoró mucho en cuanto cambiaron el i9 por un i7
      Al final caímos en el marketing de “número más grande = mejor CPU”
    • Yo también tuve el mismo problema, especialmente al conectar dos monitores externos
      Después me cambié a una M1 Max y fue otro mundo por completo
      Ahora ya subí a una M3 Max, y Apple Silicon parece que va a durar bastante
    • Esa laptop fue la peor computadora que he usado en mi vida
      Los ventiladores arrancaban apenas iniciaba, y al conectar dispositivos Thunderbolt también tenía kernel panics muy seguido
      La MBP M1 Max que uso ahora es perfectamente estable
  • El proyecto se ve bastante bien
    Pero como desarrollar en macOS es cada vez más difícil, me pregunto qué se puede hacer realmente aunque detectes el throttling
    ¿Ni siquiera se puede ajustar la velocidad de los ventiladores, y tampoco hacer undervolting, no?

    • En mi caso, ajusté manualmente la curva de ventiladores con iStat Menus
      La curva predeterminada era tan lenta que primero ocurría el throttling
      En Apple Silicon, si usas High Power Mode, los ventiladores giran más rápido
      Ahora ya no uso una curva personalizada, pero en la 14" M4 Max hace bastante ruido
      La MacBook Air no tiene ventiladores, así que solo queda intentar disipar el calor
    • Yo uso Macs Fan Control para ajustar las RPM del ventilador según la temperatura del CPU
      Con la configuración predeterminada pasaba de 90 grados, así que la dejé más conservadora
      Enlace de GitHub
    • Justo hacía falta una app así, y por fin apareció
      A veces algún proceso se descontrola y causa throttling, y para cuando me doy cuenta, la batería ya va por la mitad
    • Al final, lo único que puedes hacer es cerrar la app o tomarte una pausa
      Este problema pasa seguido cuando hay muchas apps corriendo en segundo plano
  • Si lo publican en Homebrew, pueden obtener firma de código y notarización gratis
    Estaría muy bien que se distribuyera así

    • Buen dato. Me pregunto si también existe algún método gratuito de firma para Windows
    • Oh, no lo sabía. Pensé que dependía de la configuración del desarrollador, tendré que investigarlo
  • Mi hipótesis es que el problema no es el CPU, sino que el controlador USB satura térmicamente el sistema
    Más que CPU/GPU, parece que el chasis se sobrecalienta, se bloquea la disipación y al final aparece el throttling
    Habría que probar con otros adaptadores o monitores

    • Yo también uso una i9 de 2019, y al cambiar el puerto de carga desapareció el throttling
      Creo que tienes razón
    • No lo entiendo del todo, pero mi M2 Air también tiene síntomas parecidos
      Si la conecto a un monitor 4K 144Hz y abro Zoom o varios streams de video, se calienta muchísimo
      Más que por el controlador USB, parece simplemente por la carga elevada
    • A este fenómeno le llaman thermal soaking
  • Parece que el sitio se cayó por un pico de tráfico
    El repositorio es angristan/MacThrottle

    • Ya quedó corregido. Cloudflare Workers estaba configurado en modo fail closed y por eso estaba bloqueando el tráfico
  • Si en iStat Menus ves el CPU al 100% pero con bajo consumo de energía, podrías pensar que es throttling,
    pero lo mismo también pasa cuando está conectado a un cargador USB-C de baja potencia
    Estaría bien agregar una función para detectar la potencia del cargador

    • A mí me pasó lo mismo durante una sesión de D&D con una MacBook Air M1
      Como se calentaba más mientras cargaba, el throttling empeoraba, pero se solucionó cargándola antes de la sesión
    • Antes me pasó que la salida del adaptador de corriente era insuficiente y la batería se agotó mientras jugaba hasta que la máquina se apagó
      Ahí entendí por qué en generaciones posteriores salieron adaptadores de mayor potencia
    • Entonces me pregunto por qué no se puede determinar el throttling solo con la temperatura de los núcleos
      ¿No es esa la variable de control directa?
    • iStat Menus sí muestra la potencia del cargador, pero sigue sin estar claro por qué ocurre este fenómeno
  • Si dejas el uso del CPU y el consumo del sistema visibles en la barra de menús, puedes detectar enseguida cualquier anomalía
    exelban/stats

    • Yo justo así empecé a sospechar del throttling
      Me di cuenta al ver que el uso del CPU seguía alto pero el consumo bajaba
  • Ojalá la próxima MacBook Air M5 venga con refrigeración por vapor chamber
    Ahora mismo parece que Apple prioriza minimizar el ruido por encima de disipar el calor
    Por eso fuerzo una velocidad mínima más alta en los ventiladores

    • El vapor chamber sirve para dispersar calor en ráfagas cortas, pero al final ese calor igual termina en el cuerpo de aluminio
      Cuando el cuerpo llega al equilibrio térmico con el entorno, la capacidad de disipación toca su límite
      Si hay ventilador, con una placa de cobre y flujo de aire suele ser suficiente
      Al final es un problema de conservación de la energía
  • Parece haber un bug en la notificación de thermal pressure
    Me pregunto si en la app también te encontraste con ese problema
    Issue relacionado

    • Yo también vi que el estado no se actualizaba al usar ProcessInfo.processInfo.thermalState
      Pero con el método actual de notificación de thermald no tengo ese problema
  • Me pregunto por qué declaraste directamente la API de Darwin con @_silgen_name
    ¿No se puede acceder con import Darwin?

    • En la práctica, parece que esa API no queda expuesta solo con import Darwin