Un bug de journalisation de Codex peut provoquer des écritures de plusieurs To sur le SSD local et en user rapidement la durée de vie
(github.com/openai)- Codex écrit en continu de gros volumes de données dans la base de logs de feedback SQLite locale, et dans un environnement utilisateur, environ 37 To ont été écrits sur le SSD principal après 21 jours de fonctionnement
- Rapporté sur un an, cela représente environ 640 To, soit environ 640 écritures complètes du disque par an pour un SSD de 1 To, ce qui peut épuiser en moins d’un an l’endurance garantie de certains SSD grand public (environ 600 TBW)
- Bien qu’environ 500 000 lignes seulement soient conservées, le compteur AUTOINCREMENT dépasse 5,5 milliards d’ID, soit un écart d’environ 10 000x entre les lignes conservées et les ID d’insertion cumulés
- La cause est que le sink de logs de feedback SQLite est configuré avec la valeur globale TRACE par défaut (
Targets::new().with_default(Level::TRACE)), ce qui enregistre de façon persistante à la fois les logs internes des dépendances et les payloads bruts volumineux du protocole - Le problème a été clos après la fusion de deux PR le 22 juin 2026, qui ont bloqué environ 85 % des logs
Symptômes clés et périmètre d’impact
- Codex génère en continu d’importantes écritures dans les fichiers suivants
~/.codex/logs_2.sqlite~/.codex/logs_2.sqlite-wal~/.codex/logs_2.sqlite-shm
- Après 21 jours de fonctionnement, environ 37 To ont été écrits sur le SSD principal, et l’inspection par processus/fichier a confirmé que les logs SQLite de Codex étaient la principale source d’écritures persistantes
- Cela correspond à environ 640 To par an, soit approximativement 640 écritures complètes du disque par an pour un SSD de 1 To
- Certains SSD grand public sont donnés pour environ 600 TBW, ce qui peut épuiser leur endurance d’écriture garantie en moins d’un an
Données probantes
-
Evidence1 — amplification d’écriture (write amplification)
- Taille actuelle du fichier
logs_2.sqlite: 1,2 GiB - Lignes actuellement conservées : 506 149
row idcumulés alloués : 5 543 677 486- L’écart d’environ 10 000x entre les lignes conservées (environ 0,5 M) et les ID d’insertion cumulés (plus de 5,5 milliards) suggère plus de 10 To de churn historique des logs, même en excluant le WAL, les index, le pruning, les checkpoints, les réécritures de pages et l’amplification au niveau du périphérique
- Taille actuelle du fichier
-
Evidence2 — répartition par niveau/cible
- 681 774 lignes conservées, pour un contenu de logs conservés estimé à environ 1 035,6 MiB
- Répartition par niveau : TRACE 70,7 %, INFO 25,7 %, DEBUG 3,0 %, WARN 0,6 %
- Principales paires target+level
codex_api::endpoint::responses_websocket(TRACE) 527,4 MiBcodex_otel.log_only(INFO) 141,2 MiBcodex_otel.trace_safe(INFO) 121,2 MiBlog(TRACE) 97,4 MiB
- Les principales sources sont surtout le logging global TRACE, les logs de télémétrie dupliqués, et l’enregistrement des payloads bruts websocket/SSE
codex_otel.log_only+codex_otel.trace_safereprésentent en plus 25,3 %, et filtrer ces catégories permettrait de supprimer environ 96 % des octets de logs conservés dans l’échantillon- La source TRACE la plus fréquente (
target=log) contient de nombreux éléments bas niveau comme desinotify event(par ex.ld.so.cache128 764 fois), des appels internes à tokio-tungstenite, ou desWouldBlock
-
Mesure de l’amplification d’écriture
- Sur un échantillon de 15 secondes, le nombre de lignes conservées est resté stable à 681 774, tandis qu’environ 36 211 lignes ont été insérées
- Cela montre un schéma insert-and-prune répété — insertion → indexation → écriture WAL → pruning — qui provoque l’amplification d’écriture
Cause estimée
- Le sink de logs de feedback SQLite est installé avec la valeur globale TRACE par défaut (
Targets::new().with_default(Level::TRACE)) - En conséquence, toutes les cibles sont stockées de façon persistante au niveau TRACE, y compris les logs internes/des dépendances et les payloads bruts volumineux du protocole
Orientation de correction proposée
- Conserver les logs de feedback, mais réduire le périmètre de stockage persistant par défaut
- ne pas utiliser TRACE global pour le sink de logs de feedback SQLite
- relever le seuil ou supprimer le bruit à faible valeur comme
target=log,hyper_util, les internes de tokio-tungstenite, le spam inotify, et les logs bas niveau du SDK OpenTelemetry - au lieu de stocker l’intégralité des payloads bruts websocket/SSE, enregistrer un résumé (type d’événement, durée, succès/échec, consommation de tokens, taille du payload en octets)
- éviter de stocker les événements miroir
codex_otel.log_only/codex_otel.trace_safe, sauf lorsqu’ils sont réellement utiles au débogage - un simple plafond par thread ne suffit pas ; il faut ajouter une limite globale de taille/écriture pour la base de logs
- Une option comme
sqlite_logs_enabled = falseserait aussi utile, mais la solution centrale reste un meilleur filtrage par défaut
Rapports de reproduction multiplateforme
-
macOS
- Sur macOS 15.7.7 / Codex 26.616.51431,
logs_2.sqlitefait 113 M,MAX(id)=34,277,360pour 31 405 lignes conservées, et deux échantillons de 60 secondes ont confirmé environ 60 écritures par seconde - Un cas a signalé environ 50 Go écrits par le processus
codexpendant une session de 1 à 2 heures
- Sur macOS 15.7.7 / Codex 26.616.51431,
-
Windows
- Sur Codex Desktop pour Windows (
codex.exe app-server --analytics-default-enabled), des lignes TRACE continuent d’être insérées même sansRUST_LOG=warnni configuration explicite de trace - Environ 71k lignes conservées, et la valeur
logsdanssqlite_sequencedépasse 18,5 millions, indiquant de nombreux cycles historiques d’insert/prune - Sur une distribution de 10 minutes, on compte 1 812 lignes TRACE, avec parmi les principales cibles TRACE
codex_api::endpoint::responses_websocket(3,5MB+), ainsi quecodex_api::sse::responses - Comportement attendu : avec
RUST_LOG=warn, les TRACE internes/des dépendances et les payloads volumineux ne devraient pas être stockés de façon persistante
- Sur Codex Desktop pour Windows (
Risques supplémentaires et mesures temporaires d’atténuation
-
Risque de perte de données
- Si le disque est plein au redémarrage, la connexion Linux peut échouer
- Le mode Codex
/goalpeut tenter de libérer de l’espace disque en supprimant des fichiers/dossiers, ce qui peut entraîner une perte de données
-
Scripts temporaires d’atténuation
trim-codex-wal.sh, qui réduit le WAL en cours d’exécution viaPRAGMA wal_checkpoint(TRUNCATE), peut être exécuté toutes les 15 minutes via cronfix-codex-wal.sh, qui supprime les fichiers de log/WAL puis envoie SIGTERM → SIGKILL aux processus liés à Codex pour libérer immédiatement de l’espace disque- L’ajout d’un trigger SQLite (
block_log_inserts) qui ignore les insertions dans la tablelogsstoppe la croissance du WAL ; pour revenir en arrière, utiliserDROP TRIGGER IF EXISTS block_log_inserts- Comme
VACUUMréécrit la base, il peut provoquer une grosse écriture ponctuelle sur les gros fichiers ; il est donc recommandé d’ajouter d’abord le trigger, de confirmer l’arrêt de la croissance du WAL, puis d’exécuterDELETE/VACUUM - Comme il s’agit d’une modification d’un schéma SQLite privé, une future mise à jour/migration de Codex pourrait recréer les tables, supprimer le trigger, etc.
- Comme
- En attendant une correction permanente, il est aussi proposé de placer cette base sur un ramdisk pour éviter d’endommager le SSD
Correction et clôture
- Le 22 juin 2026, la fusion de deux PR a réduit les logs d’environ 85 %, ce qui a permis de marquer l’issue comme résolue
- arrêt de toute journalisation des événements Responses WebSocket (#29432)
- filtrage des cibles bruitées dans les logs persistants (#29457)
- Un patch proposé séparément remplace le TRACE global par un stockage par défaut en
INFO+, et relève àWARN+des cibles commecodex_otel.log_only,codex_otel.trace_safe,hyper_util,log,opentelemetry_sdk, etc. - Les correctifs ont été publiés dans
rust-v0.142.0
1 commentaires
Avis Hacker News
Codex me semble être l’un des exemples les plus notoires de slopware
Sur macOS, le simple fait de laisser la fenêtre visible fait monter le GPU à 100 % juste pour afficher le message de spinner
Sur un MBP M5, le simple message de spinner fait déjà monter le GPU à 100 %, et comme le ventilateur tourne à fond pendant la majeure partie du temps d’attente du modèle, il faut faire attention quand on est sur batterie
Ce problème est signalé sur GitHub depuis presque 6 mois, sans doute depuis la sortie de ce bric-à-brac pondu en vibe coding
Et même si on voulait le corriger soi-même, c’est impossible parce que, pour une raison que j’ignore, le code source est fermé
Il y a beaucoup de débats sur quel modèle est meilleur et sur la viabilité du vibe coding, mais voilà apparemment le niveau qu’on obtient quand l’une des entreprises les mieux dotées en financement, en effectifs et en capacités de modèles s’y met
Quand le CEO a déjà déclaré qu’il se concentrait sur le « coding », un raté aussi grave donne l’impression que quelque chose est vraiment cassé en interne, et même sur Polymarket presque personne ne pense plus qu’OpenAI va bientôt sortir un modèle de pointe
C’est tragique, parce qu’il faut bien un concurrent à Anthropic dans ce monde
J’ai l’impression que la « révolution de l’IA agentique » aurait déjà dû résoudre ce genre de problèmes
J’espère qu’en interne ils ne sont pas en train de dire « veuillez patienter pendant le traitement » ou « tâche trop difficile »
Personne ne veut devenir la vitrine publique d’une base de code pourrie
Et si en plus on s’en sert pour justifier un prix absurde, j’imagine que la pression est multipliée par trois
Je ne comprends pas
Même si j’essaie d’utiliser Google AI Studio dans le navigateur, ça prend 100 % du CPU
Je finis par me dire qu’il faut peut-être tout faire en appli native
Un contournement temporaire de ce problème a été publié sur X[1]
sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"Et sur un portable, lancer
VACUUM FULLsur ce fichier sqlite l’a fait passer de 27 Go à 73 Mo[2][1]: https://xcancel.com/bdsqlsz/status/2067964486615810369
[2]: https://xcancel.com/jeethu/status/2068087449469780434
Tout le monde critique OpenAI, et à juste titre, mais il faut rappeler qu’à la différence de Claude Code, Codex est officiellement personnalisable : https://github.com/openai/codex
C’est aussi assez facile à patcher
C’est choquant
Le ticket est ouvert depuis une semaine et, de ce que je vois, OpenAI se contente du silence
J’aurais pensé que ce genre de vendeurs serait extrêmement sensible à ce type de problème, je ne comprends pas
Ils ont évidemment branché plusieurs agents pour surveiller les issues potentielles sur GitHub et proposer des correctifs, non ? …non ?
Faire tourner leurs propres outils pour corriger des issues GitHub en temps réel, ça devrait forcément être trivial
Mon exemple préféré est le #2472 : ils ont fait une démo en disant que c’était « corrigé » pendant le lancement de GPT-5, mais le ticket est toujours ouvert et ce « correctif » n’a même pas été fusionné
Le billet original qui le souligne est ici : https://blog.tymscar.com/posts/openaiunmergeddemo/ ; et l’issue est ici : https://github.com/openai/openai-python/issues/2472
J’utilise beaucoup Codex et je suis très satisfait de ses performances (UX et résultats), mais je trouve difficile à comprendre qu’ils n’aient toujours pas corrigé ça
Ce problème semble avoir été corrigé[0] et devrait entrer dans la prochaine release
[0] https://github.com/openai/codex/commit/e98d43ac372ddf7f513c0...
Le vibe coding pousse « move fast and break things » à un tout autre niveau
Mais sur un vrai produit, un véritable ingénieur logiciel ne sera jamais remplacé
Un peu hors sujet, mais ces entreprises doivent arrêter de polluer la racine des dépôts avec des Claude.md ou copilot.md
Il faut se mettre d’accord une bonne fois pour toutes sur une structure de dossier connue comme
docs/llm/*À la fin de l’an dernier, quand Claude Code était en vrac à cause de la latence, OpenAI a laissé filer une victoire presque acquise
Aujourd’hui, Codex a déjà de la latence de frappe dès le démarrage, alors que Claude Code, même s’il se fige parfois, affiche en général mes frappes quand j’appuie sur une touche… littéralement… comme je les ai tapées
Dès que je tape plus de quelques mots, je dois toujours passer par neovim
En réalité, c’est une erreur très classique
Ils ont juste livré avec le logging de traçage / débogage activé pour tout, mais ce qui est amusant, c’est que l’impact ne se manifeste pas de la manière habituelle
Avant, un développeur activait un logging de niveau trace, l’application devenait catastrophiquement lente, et c’était corrigé tout de suite dans la mise à jour suivante ; aujourd’hui, la mémoire, le CPU et les disques sont devenus tellement plus rapides qu’on a atteint un point où ça ne se voit plus immédiatement de cette façon, ce qui est assez fou
J’aimerais que quelqu’un fasse don de quelques tokens à cette courageuse startup. Elle a l’air d’en avoir besoin