En bref
- Problème : Codex Desktop donnait une impression de ralentissement local sur mon Mac.
- Ce que j’ai testé : tailles de
~/.codex, bases SQLite, WAL et sessions JSONL archivées. - Résultat :
~/.codexest passé d’environ18 Goà9.3 Go, et une agrégation large surlogs_2.sqliteest passée de13.96sà0.09s. - À retenir : avant d’accuser le modèle ou le réseau, inspecter l’état local.
- Repo lié :
pezzos/codex-local-maintenance.
Le ralentissement qui m’a fait regarder sous le capot
Je suis parti d’un ressenti très simple : Codex devenait de plus en plus lent. Pas un bug net, pas une erreur reproductible, plutôt cette impression que l’app traîne un poids local avant même qu’une conversation ait vraiment commencé.
Mon hypothèse de départ était assez large. Dans ~/.codex, trois fichiers semblaient
pouvoir accumuler de l’historique :
state_5.sqlitelogs_2.sqlite.codex-global-state.json
Je voulais savoir si l’un d’eux ajoutait du bruit au démarrage, à la sidebar, aux vues de logs, ou aux recherches locales. Je n’avais pas encore de preuve. Juste une bonne raison de mesurer.
Ce que les tailles racontaient
Les premiers relevés ont vite déplacé le soupçon. Le fichier JSON global ne pesait que
252 Ko, donc il n’était probablement pas la source principale du problème.
Le reste était plus parlant :
~/.codexmontait à environ18 Gologs_2.sqlitefaisait2.1 Go- le WAL de
logs_2.sqlitemontait jusqu’à301 Mo, puis1.3 Gopendant les premières opérations archived_sessionsfaisait5.4 Gosessionsfaisait6.8 Go- une agrégation large sur
logs_2.sqliteprenait13.96s
Ce n’était donc pas une histoire de petit fichier de préférence mal rangé. Le poids venait surtout de la base SQLite des logs, de son WAL, et des sessions JSONL archivées.
Nettoyer sans casser l’historique vivant
Je n’ai pas voulu supprimer brutalement ~/.codex. La partie délicate, ici, est que
Codex peut être en train d’écrire dans ses bases ou dans ses sessions. Le bon ordre
était donc lent et prudent.
D’abord, inspection en lecture seule : tailles, tables SQLite, nombre de lignes, WAL, répertoires de sessions. Ensuite seulement, nettoyage hors Codex, avec l’application fermée.
Le passage manuel commençait par fixer les chemins et sauvegarder les fichiers que j’allais toucher :
export CODEX_HOME="$HOME/.codex"
export KEEP_DAYS=14
export RUN_ID="$(date +%Y-%m-%d-%H%M%S)"
export BACKUP_DIR="$HOME/Documents/Codex/codex-maintenance-backups/$RUN_ID"
mkdir -p "$BACKUP_DIR"
cp "$CODEX_HOME/logs_2.sqlite"* "$BACKUP_DIR/" 2>/dev/null || true
cp "$CODEX_HOME/state_5.sqlite"* "$BACKUP_DIR/" 2>/dev/null || true
cp "$CODEX_HOME/session_index.jsonl" "$BACKUP_DIR/" 2>/dev/null || true
Ensuite, j’ai nettoyé la base de logs. L’idée était de tronquer le WAL, supprimer les
logs trop anciens, être plus agressif sur TRACE, DEBUG et INFO, puis compacter :
sqlite3 "$CODEX_HOME/logs_2.sqlite" "
PRAGMA wal_checkpoint(TRUNCATE);
DELETE FROM logs
WHERE ts < strftime('%s','now','-14 days');
DELETE FROM logs
WHERE level IN ('TRACE','DEBUG','INFO')
AND ts < strftime('%s','now','-3 days');
VACUUM;
PRAGMA wal_checkpoint(TRUNCATE);
PRAGMA optimize;
"
J’ai appliqué le même principe de checkpoint, VACUUM et optimisation à la base d’état,
mais sans suppression de lignes :
sqlite3 "$CODEX_HOME/state_5.sqlite" "
PRAGMA wal_checkpoint(TRUNCATE);
VACUUM;
PRAGMA wal_checkpoint(TRUNCATE);
PRAGMA optimize;
"
Enfin, les sessions déjà archivées depuis plus de 14 jours sont parties en quarantaine
horodatée, hors de ~/.codex :
export QUARANTINE="$HOME/Documents/Codex/codex-archived-sessions-quarantine/$RUN_ID"
mkdir -p "$QUARANTINE/archived_sessions"
find "$CODEX_HOME/archived_sessions" \
-type f \
-name '*.jsonl' \
-mtime +14 \
-print0 |
while IFS= read -r -d '' f; do
mv "$f" "$QUARANTINE/archived_sessions/"
done
Les sessions déjà archivées depuis plus de 14 jours ont été déplacées en quarantaine,
hors de ~/.codex, au lieu d’être supprimées directement. C’est moins satisfaisant
qu’un grand ménage définitif, mais plus confortable : si une hypothèse est mauvaise, les
fichiers existent encore ailleurs.
Le résultat après passage
Après nettoyage, les chiffres ont changé franchement :
~/.codexest descendu à9.3 Goarchived_sessionsest passé de5.4 Goà894 Mologs_2.sqliteplus son WAL sont passés d’environ2.6 Goà environ595 Mologs_2.sqlite-walest revenu autour de9 Mo1 259anciennes archives, pour4.5 Go, ont été déplacées en quarantaine- la même agrégation de logs est passée d’environ
13.96sà0.09s
Le gain disque est évident, mais ce n’est pas le plus intéressant. Le temps de requête sur les logs donne une piste plus concrète : une partie de la lenteur ressentie pouvait venir de là. Je ne peux pas prouver que tous les ralentissements venaient du bloat local, mais ce nettoyage a supprimé une source plausible et mesurable.
Le petit script que je veux garder
J’ai ensuite transformé le nettoyage manuel en script de maintenance macOS. Il fait peu de choses, volontairement :
- il sort si Codex tourne ;
- il prend un lock pour éviter deux runs concurrents ;
- il sauvegarde
logs_2.sqlite*,state_5.sqlite*etsession_index.jsonlavant de modifier quoi que ce soit ; - il checkpoint et compacte
logs_2.sqlite; - il compacte
state_5.sqlite; - il déplace les vieilles sessions archivées dans une quarantaine ;
- il supprime les anciens logs de maintenance et les quarantaines trop vieilles.
Le LaunchAgent macOS utilise RunAtLoad=true, donc le script se lance au login. Ce n’est
pas un daemon permanent ; c’est juste un coup de balai au démarrage de session, quand
Codex n’est pas encore lancé.
J’ai extrait une version générique dans un petit dépôt dédié. Les chemins personnels, le
label launchd, les dossiers de logs et la quarantaine sont paramétrés ou templatisés.
Le script ne contient pas de credential.
Ce que tu peux reprendre
- la méthode d’inspection : taille disque, WAL, tables SQLite, temps de requête ;
- le réflexe de backup avant modification ;
- le principe de quarantaine plutôt qu’une suppression immédiate ;
- le script, à condition de lire ses chemins, sa rétention et ses garde-fous.
Ce qu’il ne faut pas copier aveuglément
- le lancement pendant que Codex tourne ;
- la suppression directe des sessions archivées sans quarantaine ;
- mes seuils de rétention
14jours et3jours ; - mes chemins macOS de backup et de quarantaine ;
- l’exécution automatique au login si Codex tourne déjà chez toi à ce moment-là ;
- l’idée que ce nettoyage explique tous les ralentissements Codex.
Ce que je retiens
Quand une app agentique ralentit, la réponse facile est d’accuser le modèle, le réseau, ou la conversation courante. Ici, le premier endroit utile était beaucoup plus banal : le dossier local.
Je garde surtout trois réflexes :
- mesurer avant de nettoyer ;
- déplacer avant de supprimer ;
- automatiser seulement après un passage manuel compris.
Ce n’est pas une méthode générale pour accélérer Codex. C’est une trace pratique : dans
ce cas précis, ~/.codex avait accumulé assez de logs SQLite et de sessions JSONL pour
mériter une maintenance locale.
Le repo contient
bin/codex-maintenance.sh, le script de maintenance ;- un template LaunchAgent macOS ;
RESULTATS.md, avec les mesures avant/après ;- des notes d’investigation et un scan simple de credentials.
Il sert à
- refaire l’enquête sans repartir de zéro ;
- inspecter le script et l’adapter avant de toucher à
~/.codex; - adapter une maintenance locale prudente sur macOS.
Il ne sert pas à
- promettre une accélération générale de Codex ;
- nettoyer un environnement en cours d’écriture ;
- remplacer une sauvegarde ou une lecture des fichiers qui seront déplacés.