TL;DR
Codex Desktop a un comportement assez aberrant sur macOS : personne ne l’utilise, aucune conversation n’est en cours, et pourtant le processus principal peut rester stable à plus de 250 % de CPU, alors que le sous-processus app-server, qui fait réellement le boulot, n’utilise que 0,1 % à 1,3 %. Autrement dit, le CPU n’est pas consommé par l’inférence du modèle ni par la communication avec le backend, mais par la couche desktop elle-même. Voici mes mesures locales et une analyse de stack avec sample, avec au passage l’issue que je viens d’ouvrir et quelques issues historiques liées.
Environnement
- Codex Desktop :
26.506.31421 - macOS :
26.4.1 - Machine : Mac mini M4 / 16GB
- État : fenêtre en arrière-plan, aucune session active, seulement des conversations historiques présentes
Symptôme
Observation continue avec top / Activity Monitor :
- Processus principal de Codex : 264 % – 285 % CPU, sans redescendre sur la durée
- Sous-processus
codex app-server: 0,1 % – 1,3 % - app-server a une faible utilisation ; rien n’indique que le modèle ou les calculs backend soient le goulot d’étranglement
Intuitivement, on peut facilement se tromper et penser que « le modèle / le backend bosse en douce », mais les données du sous-processus invalident directement cette hypothèse.
Ce que fait la stack sample
En capturant le processus principal avec sample, le hot path ressemble grosso modo à ça (extrait, sauvegardé dans /tmp/codex-main-665.sample.txt) :
uv__io_poll
└─ node::LibuvStreamWrap::OnUvRead
└─ node::StreamBase::CallJSOnreadMethod
└─ <JS / V8 frames>
└─ Buffer / ArrayBuffer ops
└─ memmove / bzero
Les indices sont très clairs :
- Toute la chaîne passe par libuv → Node stream → callback JS
- Beaucoup de temps est passé dans des copies de Buffer / ArrayBuffer (
memmove,bzero) - Aucun symbole lié au ML / à l’inférence, ni stack de client HTTP
Donc il s’agit de Node IPC / traitement de flux local dans le rendu ou le processus principal d’Electron qui tourne à vide ou déplace des données en boucle, rien à voir avec le modèle lui-même.
Deux facteurs d’amplification évidents
Pendant l’enquête, j’ai trouvé deux choses qui, prises séparément, ne sont pas forcément fatales, mais qui, combinées, peuvent facilement gaver ce hot path :
1. Taille anormale de ~/.codex/sessions
du -sh ~/.codex/sessions
# 596M
- Le plus gros historique JSONL individuel : 178M
- Plusieurs autres gros fichiers d’historique autour de ~60M
Si le client desktop scanne, lit ou préchauffe ces historiques de session au démarrage ou en période d’inactivité, faire passer un JSONL de 178M dans la chaîne Node stream → JS Buffer coûte très cher, et ça colle parfaitement au motif memmove/Buffer observé dans sample.
2. Échecs répétés de git rev-parse dans des dépôts git vides
Dans les logs, on voit git rev-parse être exécuté à répétition sur plusieurs workspaces, avec des échecs en exit 128, et les erreurs suivantes :
fatal: ... does not have any commits yet
fatal: not a valid object name HEAD
Autrement dit, ces répertoires sont des « dépôts à moitié faits » après git init, mais sans aucun commit et sans HEAD. Le client desktop semble sonder HEAD en boucle sur eux, échouer à chaque fois puis réessayer, ce qui ajoute encore une charge constante à vide.
L’issue que j’ai ouverte
Nouvelle issue que je viens de soumettre, avec la stack sample et les données de ma machine :
Issues historiques liées (symptômes / pistes proches, pour référence)
- Codex desktop app pegs CPU on macOS after latest update; fans surge and system lags even on small requests · Issue #18467 · openai/codex · GitHub
- High CPU usage / overheating on macOS when running scripts or making edits in Codex app · Issue #18481 · openai/codex · GitHub
- Codex App: non-git saved workspace roots can trigger renderer high CPU and Git warning loops · Issue #19115 · openai/codex · GitHub
- Desktop performance collapses in profiles with a few very large local conversation histories (typing, scrolling, thread list, random exits) · Issue #18693 · openai/codex · GitHub
- **Feature negotiation mismatch in 26.506.31421 — JS bundle requests features Rust app-server doesn't support, triggers extension host termination · Issue #21911 · openai/codex · GitHub
Dans ces issues, on retrouve des descriptions similaires de « CPU élevé au repos / utilisation anormale du processus principal ». Je n’ai pas vu de conclusion officielle claire sur un correctif, donc ce post ne prétend pas non plus que le problème est résolu.
Contournements temporaires (testés, avec amélioration chez moi)
En attendant un correctif officiel, on peut essayer :
- Redémarrer Codex Desktop : ça remet immédiatement le CPU du processus principal à un niveau normal, mais le problème revient après un certain temps. C’est donc un pansement.
- Archiver / nettoyer les très gros historiques de session : déplacer ailleurs, en sauvegarde, les JSONL particulièrement gros dans
~/.codex/sessions(ceux qui font plusieurs dizaines de Mo ou plus). Une fois la taille réduite, le CPU au repos devient nettement plus stable. - Traiter les dépôts git vides : pour les workspaces en
No commits yet, soit ajouter un commit initial pour que HEAD existe, soit supprimer carrément les répertoires.gitinutiles, afin d’éviter que le client desktop échoue en boucle surgit rev-parse. - Ne pas suspecter d’abord le modèle / le backend pendant le diagnostic : commencer par regarder le CPU du sous-processus
app-server. S’il est bas alors que le processus principal est haut, on peut quasiment isoler le problème au niveau Electron/Node, pas du réseau ni de l’inférence.
Conclusion
Le piège ici n’est ni un « modèle lent » ni un « réseau lent », mais la couche IPC / traitement de flux du client desktop elle-même, amplifiée par de gros fichiers d’historique et des dépôts git anormaux. J’espère que ce retour d’expérience aidera les personnes qui rencontrent les mêmes symptômes. N’hésitez pas aussi à ajouter vos propres stacks sample et la taille de ~/.codex/sessions dans l’issue : plus il y aura d’échantillons, plus ce sera facile à localiser.